Dynamically switch ng-include between controllers - angularjs

I have the following bit of code for my navigation that I want to update dynamically between pages.
<nav ng-include="menuPath"></nav>
Here is my app and routing set up
var rxApp = angular.module('ehrxApp', ['ngRoute']);
// configure our routes
rxApp.config(function ($routeProvider) {
$routeProvider
.when('/', {
controller: 'mainController',
templateUrl: '/content/views/index.html'
})
.when('/census', {
templateUrl: '/content/views/admission/census.html',
controller: 'censusController'
})
.when('/messages', {
templateUrl: '/content/views/account/messages.html',
controller: 'messagesController'
})
.when('/profile', {
templateUrl: '/content/views/account/profile.html',
controller: 'profileController'
})
});
In my main controller I set the menuPath value here:
rxApp.controller('mainController', function (userService, $scope, $http) {
evaluate_size();
$scope.menuPath = "/content/views/index.menu.html";
});
rxApp.controller('censusController', function ($scope, $http, $sce, censusService) {
$scope.menuPath = "/content/views/admission/census.menu.html";
evaluate_size();
});
When the page switches to the census view it should change the menu. What happens though is the first page loads the main menu, then no matter what other page you go to the menu never updates.

I imagine this problem has something to do with a primitive values and prototypical inheritance between child scopes, but would need to see more of your html to determine that. Without that, I propose an alternative way that may solve your problem and keep the config all in one place.
$routeProvider will accept variables and keep them on the route, even if angular doesn't use them. so we modify your routing by including the menuPath like so:
var rxApp = angular.module('ehrxApp', ['ngRoute']);
// configure our routes
rxApp.config(function ($routeProvider) {
$routeProvider
.when('/', {
controller: 'mainController',
templateUrl: '/content/views/index.html',
menuPath: '/content/views/index.menu.html'
})
.when('/census', {
templateUrl: '/content/views/admission/census.html',
controller: 'censusController',
menuPath: '/content/views/admission/census.menu.html'
})
.when('/messages', {
templateUrl: '/content/views/account/messages.html',
controller: 'messagesController'
})
.when('/profile', {
templateUrl: '/content/views/account/profile.html',
controller: 'profileController'
})
});
Remove setting $scope.menuPath from each controller, then finally add a watch on rootScope that will change the menuPath on $routeChangeSuccess
rxApp.run(['$rootScope', function ($rootScope) {
$rootScope.$on('$routeChangeSuccess', function(event, current) {
if (current && current.$$route && current.$$route.menuPath) {
$rootScope.menuPath = current.$$route.menuPath;
} else {
$rootScope.menuPath = '';
}
});
}]);

Related

broadcast and emit does not work with ng-router?

I want pass the value to one nerds controller to geek controller but unable to pass in ng-router.
<button type="Submit" ng-click="showUser()">Show Details</button>
.when('/geeks', {
templateUrl: 'views/geek.html',
controller: 'GeekController'
})
.when('/nerds', {
templateUrl: 'views/nerd.html',
controller: 'NerdController'
})
In Nerds controller I have this function
$scope.showUser=function(){
$rootScope.$broadcast('btnName',{message:"msg"})
}
In geek controller I receiving the value on page load itself but i am not getting the value pls help me to find the solution
$rootScope.$on('btnName',function(event,args){
$scope.msg=args.message;
console.log("$scope.message nnnn",$scope.msg)
})
The NerdController and the GeekController are in two separate pages, only one of the controllers can be active at a time, since angular has only one page open in the tab. So what I suggest is, pass the variable as a parameter to the route, you can see this in the example below.
JSFiddle Demo
JS:
var routingExample = angular.module('Example.Routing', []);
routingExample.controller('NerdController', function ($scope, $location) {
$scope.showUser = function(){
console.log("show");
$location.path('/geek/1');
}
});
routingExample.controller('GeekController', function ($scope, $routeParams) {
$scope.id = $routeParams.id;
});
routingExample.config(function ($routeProvider) {
$routeProvider.
when('/nerds', {
templateUrl: 'home.html',
controller: 'NerdController'
}).
when('/geek/:id', {
templateUrl: 'blog.html',
controller: 'GeekController'
}).
otherwise({
redirectTo: '/nerds'
});
});

$scope not updated - controller specification

I have the following routing:
app.config(['$routeProvider',
function ($routeProvider) {
$routeProvider.
when('/panel', {
templateUrl: 'views/panel.html'
}).
when('/make', {
templateUrl: 'views/makePanel.html',
controller: 'painelCtrl'
}).
when('/paneluser', {
templateUrl: 'views/panelUser.html',
controller: 'userCtrl'
}).
when('/paneluserblocks', {
templateUrl: 'views/userPanels.html',
controller: 'userCtrl'
}).
when('/registred', {
templateUrl: 'views/registredPanels.html'
}).
when('/color', {
templateUrl: 'views/color.html',
controller: 'alarmCtrl'
}).
otherwise('/', {
templateUrl: 'Index.html',
});
}]);
When I specify a controller for a particular html template, my $scope variables are no longer updated in the view.
When I pull out the controller specification for a particular route, things return to normal.
The controller 'userCtrl' is accessed through $location and is intended for ordinary users. In turn, 'Ctrl panel' is the primary controller assigned to admin users.
Could anyone tell me what's going on?
I haven't all information, but it's working in my demo.
Config
var app = angular.module('app',['ngRoute']);
app.config(['$routeProvider',
function ($routeProvider) {
$routeProvider.
when('/panel', {
templateUrl: 'views/panel.html'
}).
when('/make', {
templateUrl: 'views/makePanel.html',
controller: 'painelCtrl'
}).
otherwise('/', {
templateUrl: 'Index.html',
});
}]);
Definition of your controller:
app.controller('painelCtrl',painelCtrl);
painelCtrl.$inject = ['$scope'] //and more if you need $http, services, ...
function painelCtrl($scope){
$scope.hello= "hello world"
}
HTML
<h1>{{hello}}</h1>
I'm sorry for the igenuidade. I believed that the pages being in the same controller, I would never miss the reference:
When ('/panel', {
TemplateUrl: 'views/panel.html',
Controller: 'panelCtrl'
}).
When ('/make', {
TemplateUrl: 'views/makePanel.html',
Controller: 'panelCtrl'
}). cotinue...
In fact, views panel.html and makePanel.html will use the same controller structure, however we will have one instance for each view (variables will be reseted).
In my case I used factory functions to solve the problem. Every time I mute controller, I store the information of interest through a set () and get it through a get ();
app.factory("MonitorService", function () {
var info;
function set(data) {
info = data;
}
function get() {
return info;
}
return {
set: set,
get: get
}
});

Separate nav from ng-view

I'm brand new to Angularjs and am trying to set up a new site but I'm confused as to the set up. I have a module and am using $route to successfully navigate but I'm lost as to what to do with my nav. When I load the module I want to read my database for a list of links that the user is allowed to access then spit them out in the nav. I don't want to repeat this in every view because I don't need to. So I'm trying to figure out how to run the ajax call once and then keep changing the view (I'd also like to add a class .selected to whatever view they're on). How would I go about doing that, with a directive?
(function () {
var app = angular.module('manage', ['ngRoute', 'manageControllers']);
/*
I've tried this but obviously $http isn't injected. Can I even do that?
var thisApp = this;
$http.get('/test/angular/php/angular.php', {params: {'function': 'nav'}}).then(function successCallback(response) {
});
*/
app.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/', {
templateUrl: 'templates/dash.html',
controller: 'DashCtrl'
}).
when('/inventory/', {
templateUrl: 'templates/inventory.html',
controller: 'InventoryCtrl'
}).
when('/inventory/:mvKey', {
templateUrl: 'templates/inventory.html',
controller: 'InventoryCtrl'
}).
when('/inventory/:mvKey/:tab', {
templateUrl: 'templates/inventory.html',
controller: 'InventoryCtrl'
}).
/* etc...*/
}
]);
})();
EDIT:
My attempt at getting the nav to run once
controllers.js
var manageControllers = angular.module('manageControllers', []);
var thisApp = this;
nav = null;
navSelected = '/';
manageControllers.controller('NavCtrl', ['$scope', '$http', function($scope, $http) {
if (thisApp.nav === null) {
$http.get('php/angular.php', {params: {'function': 'nav'}}).then(function successCallback(response) {
console.log(response.data);
thisApp.nav = response.data;
$scope.nav = thisApp.nav;
$scope.select = thisApp.navSelected;
});
} else {
$scope.nav = thisApp.nav;
$scope.select = thisApp.navSelected;
}
}]);
manageControllers.controller('DashCtrl', ['$scope', function($scope) {
thisApp.navSelected = '/';
}]);
I would swith to UI Router (https://github.com/angular-ui/ui-router) instead of $route. It allows you being much more flexible with your routing.
A Small example:
app.config(['$stateProvider',
function($stateProvider) {
$stateProvider.
state('/', {
url: '/',
views: {
'': {
templateUrl: 'templates/dash.html',
controller: 'DashCtrl'
},
'nav#': {
templateUrl: 'path/to/nav.html',
controller: 'NavCtrl'
},
}
}).
state('/inventory/', {
url: '/',
views: {
'': {
templateUrl: 'templates/dash.html',
controller: 'DashCtrl'
},
'nav#': {
templateUrl: 'path/to/nav.html',
controller: 'NavCtrl'
},
}
}).
// ...
and in your index.html
<div ui-view="nav"></div>
<div ui-view ></div>
Take a closer look at UI Router's doc, there's much more you can do with it!

Is the page loading twice

When the page loads, the alert fires twice. I am expecting it to fire only once.
This is causing duplicate data insertion in an array inside init function.
Why is this happening. Is it something to do with the routing definitions. How to stop it.
indexctrl.js:
app.controller("indexctrl", function ($scope, $routeParams) {
var uPId = $routeParams.pqid;
var uCId = $routeParams.cid;
if (uPId != null && uCId != null) {
//some other code
}
else {
alert('test');
init();
}
var init = function(){
//some code
}
}
app.js:
var app = angular.module('app', ['ngRoute']);
app.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'App/views/index.html',
controller: 'indexctrl'
})
.when('/Index', {
templateUrl: 'App/views/index.html',
controller: 'indexctrl'
})
.when('/Index/pqid/:pqid/cid/:cid', {
templateUrl: 'App/views/index.html',
controller: 'indexctrl'
})
.otherwise({
redirectTo: '/'
});
}]);
1. Check your controller is declared in html file as well.
2.The link which is referring to routes should be like this <a href="#/Index">
3.If your working with another frame works like ionic. it has aleardy angular.js file.so check how many time your loading script file.

how to put the condition which set the template url to load

I would like to have two main pages (logged in, logged out), which have url like '/'.
Is it posiible to do it with ngRoute?
I was searching the soltion but everywhere was to use ui-router.
Now I have sth like:
$rootScope.$on('$routeChangeStart', function (event, next) {
if ( next.$$route.orginalPath == '/' && loggedIn ) {
next.$$route.templateUrl = "app/main/main-loggedIn.html"
} else {
next.$$route.templateUrl = "app/main/main-loggedOut.html"
}
});
and
angular.module('name').config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'app/main/main-loggedOut.html',
controller: 'MainCtrl'
})
});
but it doesn't work well. It changes the templateURL but it get data before that changings and load always loggedOut page.
I have also the solution to put both html in one file in set them ng-if, but I prefer to avoid it.
solution:
main.html
<div ng-include="mainTemplate"></div>
main.js
angular.module('bookkeepingApp').config(function ($routeProvider) {
$routeProvider.when('/', { controller: 'MainCtrl', templateUrl: "app/main/main.html" })
}).controller('MainCtrl', function ($scope, Auth) {
$scope.$watch(function($scope) {
return $scope.mainTemplate = Auth.isLoggedIn() ? 'app/main/main-loggedIn.html' : 'app/main/main-loggedOut.html';
})
});
I don't know how you're getting the loggedIn value, but templateUrl accepts a function as value, you just have to return the correct one, based on the information of the user. I guess the code above might work.
angular.module('name').config(function ($routeProvider) {
$routeProvider
.when('/', {
controller: 'MainCtrl',
templateUrl: function() {
return loggedIn ? "app/main/main-loggedIn.html" : "app/main/main-loggedOut.html"
}
})
});
You can put a template within a template, i.e in your route "/" you have a
<div ng-include="scopeVariable">
</div>
the scope variable points to a loggedin/loggedout page depending on your needs.

Resources