AngularJS nested controllers - javascript

I have an AngularJS app with 2 routes /home and /about.
I'm using ng-router and each route has different controllers HomeCtrl and AboutCtrl. The default route is /home.
The thing is that before display the content I want to add a preloader, just a simple div which will hide when the content is loaded.
<div class="myApp">
<div class="preloader"></div>
<div ui-view></div>
</div>
My question is, in which controller should I add this?
Should I add a new controller outside the ng-view for this kind of stuff?
Can someone explain me best practice?

I suppose the best way to do this is to use flag for data loaded indication directle in controller. So depend on this flag with ng-if directive you can show 'div' with loading indicator if dataLoadedFlag is false and div with your data otherwise.

You have ng-view, and your views render over there with its corresponding controller.
So the only thing you need ng-if
<ng-view>
<div ng-if="!$scope.contentIsReady">
content loading
</div>
<div ng-if="$scope.contentIsReady">
content here
</div>
</ng-view>

#Hiero In your case of course, you have to create new controller.
Also you can use nested views. Something like this:
$stateProvider.state('home', {
url: '/home',
views: {
"main": {
templateUrl: '....',
controller: '....'
},
'view-with-data#home': {
templateUrl: '...',
controller: '...',
}
}
});
See more at https://github.com/angular-ui/ui-router/wiki/Nested-States-&-Nested-Views

Related

Multiple controller for same view in AngularJS?

Is there any way that I can define two controller for the same templateUrl in angularjs using stateProvider like below?
//State Provider for dashBoard Screen
.state('dashBoard', {
cache : false,
url : "/dashBoard",
templateUrl : dashBoardHtml,
controller : ["FirstController","SecondController"]
})
The data binding logic is to heavy in my controller, the number of line is more than 1000, I have optimised, reduced cyclometic complexity everything.
But now to make it more modularize I need to split the controller without change in the view like by not using any nested views.
Is there any way to define multiple contollers to same templateURL/html?
I think you can put them into several services for business logic or directives for UI logic to make your code more clear and tidy.
This will work for you but if you want then you can use ng-controller directive as well
$stateProvider.state('view', {
url: "/url",
views: {
'menuContent': {
templateUrl: "template",
controller: ['ctrl1', 'ctrl2']
}
}
});
example using diretive
<div ng-controller="testController2">
<!-- your view content -->
</div>
<div ng-controller="testController1">
<!-- your view content -->
</div>
You can only assign one controller from the state and other one inside template like this
.state('dashBoard', {
cache : false,
url : "/dashBoard",
templateUrl : dashBoardHtml,
controller : FirstController
})
template
<div data-ng-controller="SecondController">
<!-- your view content -->
</div>
your can assign controller on html
<div ng-controller="controller1"></div>
and on same HTML on other div
<div ng-controller="controller2"></div>

Angular ui-router loads neither template nor controller?

I use ui-router for moving between pages, without reloading.
Here is one of my states:
$locationProvider.html5Mode({enabled: true, requireBase: false});
$stateProvider
.state('aboutBook', {
url: '/book/about/:bookId',
templateUrl: '/views/books/about-book.tpl.html',
controller: 'AboutBookCtrl'
})
Here I have ui-view div in my index.php file.
<div ui-view></div>
When I go to the /book/about/9874365942 page, I have both controller and template accessible, but ui-router doesn't load neither template nor controller.
What can cause such behavior? How can I fix it?
Note: ng-include, loads template just file
<div ng-include="'/views/books/about-book.tpl.html'"></div>
Update: $stateChangeStart and $stateChangeSuccess events aren't triggered as well.

Multiple Views with nested views Angular

So first off, I'm working on this for a project at work, but none of us have any idea how to do it, so it might be kind of vague.
Here is the template of how it is going to look: Template
So View A & B are going to have 3 states in them that will change the content of the view based on which one is selected
The problem I'm having is that only 1 view ever shows up and it is a test template for now because I don't have those views built but none of the sub views of View A ever show up.
HTML
<div id="main">
<div ui-view="viewa" class="col-sm-7">
<!--Content of ViewA supposed to be here-->
</div>
<div ui-view="viewb" class="col-sm-5">
<!--Content of ViewB supposed to be here-->
</div>
</div>
States:
$stateProvider.state("main", {
url: "/main",
views: {
"viewa#": {
abstract: true,
template: "<div ui-view></div>"
},
"viewb#": {
templateUrl: "btemps/default.html"
}
}
}).state("bobtheView", {
parent: "viewa",
//This is default for viewa
url: "/",
templateUrl: "atemps/bob.html",
controller: "bobController"
}).state("billtheview", {
parent: "viewa",
url: "/bill",
templateUrl: "atemps/bill.html",
controller: "billController"
}).state("joetheview", {
parent: "viewa",
url: "/joe",
templateUrl: "atemps/joe.html",
controller: "joeController"
});
//Supposed to route to viewa showing bobtheview and viewb showing the template
$urlRouterProvider.otherwise("/main/");
So when I go to the page and go to the root it redirects to the otherwise but nothing shows up, upon just going to main, only the viewb template shows up.
Any ideas? Any way I can format it better too? Is it better to go with "viewa.bobtheview" over having the parent attribute in the mix?
UPDATE: So I found a work around, I loaded each of the bobtheview, joetheview and billtheview in html partials, then I refactored it so the view state of viewa and viewb are controlled within a main template that includes the "ng-include" function to load the different templates, and since all of the data that is stored in those views is given via JSON rest requests, there is no change in the data bindings. The problem I'm facing now, is updating that "ng-include" on button click, I haven't done extensive research on it but I plan on doing so and I'll report back when/if I find something. If you have any ideas on this let me know! :D.
So I found a viable answer to the question at hand, after extensive research and asking around, I went with the option of having 1 Controller and configuration state
$stateProvider.state("main", {
url: "/",
controller: "mainController",
templateUrl: "temps/primary.html"
});
$urlRouterProvider.otherwise("/");
That went into the configuration settings, then my controller looked a little like this:
app.controller("mainController", ["$scope", "$state", "$stateParams", "$http", function($scope, $state, $stateParams, $http) {
$scope.viewatemp = $stateParams.at; //Numeric value to represent template url for viewa
$scope.viewbtemp = $stateParams.bt; //Numeric value to represent template url for viewb
//Do some other stuff here
});
Then the HTML of "temps/primary.html" looked a little something like this:
<div ui-view="viewa" class="col-sm-5" ng-include="viewatemp"></div>
<div ui-view="viewb" class="col-sm-7" ng-include="viewbtemp"></div>
I did a little manipulation of the numeric value of viewatemp and viewbtemp to get the actual URL, those are being loaded from a JSON request from my ASP.net WebApi 2 Restful service, but all in all, it is quick, rather simple and still gets the job done and allows for further enlargement of the project.
And that there in solved my problem, cool thing about this, I can have as many as these as I want because they are all separate states with nested "views"
If you do have a better answer, let me know! This is only what I found and what worked for me.

Angular multiple views render with stateProvider - ui.router

I have a mind bugging problem. I`m new to Angular and I want to obtain the following behavior:
I have a defaultView in app.js:
$stateProvider
.state("defaultView", {
url: '/home',
controller: "MatrixController",
templateUrl: "assets/js/angular/templates/matrix.html"
})
.state("defaultView.createDiet", {
url: '/create-diet',
controller: "ModalController",
templateUrl: "assets/js/angular/templates/createDietModal.html"
});
And in the default view, I have:
<div class="wrapperCalendar" ui-view>
<div data-ui-view="defaultView"></div>
<div data-ui-view="createDiet"></div>
</div>
Basically I am trying to achieve an opening of a dialog (bootstrap modal) that is brought from another route, but I don't want to change the main view (defaultview). I just want to get the HTML for the dialog, insert it in the page without losing another section, and open it. Do you have any idea how can I acomplish that ?

AngularJS - UI-Routing - how to use the route state as variable in controller?

I am using Angular JS and UI-Routing. The routing works fine. My problem is showing and hiding a slider depending on what page the user is on.
My index.html looks something like this:
<body ng-app="myApp">
<header ng-include="'templates/header.html'"></header>
<div>Code for slider</div>
<!--=== Content Part ===-->
<div class="container">
<div class="row" >
<div ui-view autoscroll="false"></div>
</div>
</div><!--/container-->
<!-- End Content Part -->
<footer ng-include="'templates/footer.html'"></footer>
my app.js looks like this:
angular
.module('myApp', ['ui.router'])
.config(['$urlRouterProvider','$stateProvider',function($urlRouterProvider,$stateProvider){
$urlRouterProvider.otherwise('/');
$stateProvider
.state('home',{
url: '/',
templateUrl: 'templates/home.html'
})
.state('about',{
url: '/about',
templateUrl: 'templates/about.html'
})
.state('contact',{
url: '/contact',
template: 'CONTACT'
})
}])
.controller()
Now I tried to include the slider in the home.html template but then it does not properly work due to initialisation requirements. When I use a controller in the different routes it is out of scope. So how do I pass a variable referring to the state to a controller indepent of the route so I can use it for it something like
if (state==home) {
$scope.showSlider==true;
}else{ $scope.showSlider==false;}
Thanks,
Gerd
UPDATE:
#Chris T
I have added this to my app.js:
.controller('myController',['$scope', '$state', function($scope,$state){
if ($state.includes('home')){
$scope.showIt=true;
}else{
$scope.showIt=false;
}
}])
Then I applied the controller to a div I wrapped around the slider and used
ng-show="showIt"
Inject $state into your controller. Then check if $state.includes("home");
Update:
I made a plunk with a parent state which controls the slider enabled/disabled based on $state.includes('main.home')
http://plnkr.co/edit/eT1MW0IU53qfca6sGzOl?p=preview

Categories

Resources