Multiple Controllers for one view angularjs - javascript

I would like to know if it is possible to use multiple controllers for a single url view using angluarjs, I have not been able to find much documentation on this. I would like to use a controller on all pages to switch the page header title, but some pages already contain a controller
app.js
subscriptionApp.config(['$routeProvider',function($routeProvider){
$routeProvider.
when('/billinginfo',{templateUrl:'views/billing-info.html', controller:'billingInfoController'}).
when('/orderreview',{templateUrl:'views/order-review.html', controller:'billingInfoController'}).
when('/subscribed',{templateUrl:'views/subscribed.html', controller:'subscribedTitle'}).
//EXAMPLE: HOW COULD I ADD TWO CONTROLLERS TO SAME PAGE??? THIS DOES NOT WORK
when('/subscribe',{templateUrl:'views/subscribe.html', controller:'subscriptionController', 'testControllerTitle'}).
when('/unsubscribed',{templateUrl:'views/cancelconfirm.html', controller:'unsubscribedTitle'}).
when('/redirectBack',{templateUrl:'views/redirect-to-app.html'}).
when('/redirectHandler',{templateUrl:'views/redirect-handler.html',controller:'redirectController'}).
when('/error',{templateUrl:'views/error.html', controller:'messageController'}).
otherwise({redirectTo:'/subscribe'});
}]);
EDIT
I am trying to add a title controller to each page view:
function testControllerTitle($rootScope, $scope, $http) { $rootScope.header = "Success!"; }
If I add this controllers to the pages that don't already have a controller it works, if there is another controller in place I can't make this work.
<h1 ng-bind="header"></h1>

Yes, controllers and templates are independent, check this http://jsbin.com/wijokuca/1/
var app = angular.module("App", ['ngRoute']);
app.config( function ( $routeProvider ) {
$routeProvider
.when('/a', {templateUrl: 'this.html', controller: "aCtrl"})
.when('/b', {templateUrl: 'this.html', controller: "bCtrl"})
.when('/c', {templateUrl: 'that.html', controller: "bCtrl"})
.otherwise({redirectTo: '/a'});
});
app.controller('aCtrl', function ($scope) {
$scope.all = [1,2,3];
});
app.controller('bCtrl', function ($scope) {
$scope.all = [4,5,6];
});

Related

AngularJS works once then no longer renders

So I am trying to list out some data from an API call, which is JSON. I am new to Angular and JavaScript and I think the whole Async thing is messing with my logic. Sometimes when I refresh the page, it works perfectly, all the data I expect to be there is, but then the next time I refresh its gone. This seems to happen when I change something in the controller.
var app = angular.module("hasRead", ['hasRead.controllers', 'hasRead.directives', 'hasRead.services', 'hasRead.filters','ngRoute']);
app.config(["$routeProvider", function ($routeProvider) {
$routeProvider
.when("/books/:shelf", {controller: "BooksCtrl", templateUrl: "partials/books_list.html"})
.when("/recomend", {controller: "RecomendCtrl", templateUrl: "partials/recomend.html"})
.otherwise({redirectTo: "/books/read"})
}]);
controller.js
var ctrls = angular.module('hasRead.controllers', []);
ctrls.controller('AppCtrl', function ($scope) {
});
ctrls.controller('BooksCtrl', function ($scope, $book, $routeParams) {
$scope.books;
var shelf = $routeParams.list;
$book.getBooks(shelf).then( function(data) {
$scope.books = data.query.results.body.goodreadsresponse.reviews;
console.log($scope.books);
$scope.$apply;
});
});
ctrls.controller('RecomendCtrl', function ($scope) {
$scope.test = "testing";
});
HTML
<div>
<book ng-repeat="review in books.review" review-data="review"></book>
</div>
Its a fair bit of code so here is a plunkr:
https://plnkr.co/edit/l3A6QF?p=info
I didn't have the parentheses in $scope.$apply(); in the controller.

AngularJS, How about multiple routes with different templates but the same controller?

i'm investigating if i can have what the title says.
Here's my thought.
Let's assume that i've got this routes:
.when('/', {
templateUrl : 'partials/homepage.html',
})
.when('/test', {
templateUrl : 'partials/test.html',
})
.when('/page/:pageID', {
templateUrl : 'partials/page.html',
})
.when('/page/single/:pageID', {
templateUrl : 'partials/page-single.html',
})
Until now i had the opportunity to add the templateUrl as also the controller details in the route and everything was working just fine.
Now the app is changed and there is only one controller with all the information needed and must remain one controller. And the routes will be something like that:
.when('/:templateName/:pageID', {
controller: 'myCtrl'
})
Can i set from the controller the template id by getting the templateName parameter? And if so how about the last route example /page/single/:pageID? How can i know that there is a second option in route?
I can take the templateName parameter and see it changing with the $routeChangeSuccess method but i cannot find any way to set the template on the fly.
Any ideas?
One solution could be the following one:
angular.module('myapp', []).
config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/:templateName/:pageId', {
templateUrl: function(urlattr){
return '/pages/' + urlattr.templateName + '.html';
},
controller: 'YourCtrl'
});
}
]);
From the AngularJs 1.3 Documentation:
templateUrl – {string|function()} – path or function that returns a path to an html template that should be used by ngView.
If templateUrl is a function, it will be called with the following parameters:
Array.<Object> - route parameters extracted from the current $location.path() by applying the current route
I would move your singleton logic from your controller to a service. Since you didn't provide much code below is an example to give you an idea how it could work.
app.config(function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'partials/homepage.html',
controller: 'SingleController'
})
.when('/test', {
templateUrl: 'partials/test.html',
controller: 'SingleController'
})
.when('/page/:pageId', {
templateUrl: 'partials/page.html',
controller: 'SingleController'
});
});
app.provider('appState', function() {
this.$get = [function() {
return {
data: {}
};
}];
});
app.controller('SingleController', function ($scope, appState) {
$scope.data = appState.data;
});
But if it must be a singleton controller you actually could use the ng-controller directive before your ng-view directive so it becomes a $rootScope like scope for all your views. After that just add empty function wrappers in your $routeProvider for the controllers.

AngularJS controller called every time after ngRoute url is clicked

I have problem with below code. When I go to main controller url #/, Angular naturally calls main controller - it execute AJAX request. Problem is, that when I click #/some-url, and then #/ url again, this AJAX request is executed again, which is not desired and unnecessary due to performance. I thought controllers are called only once, but it doesn't look like this is the case, at least with ngRoute.
angular.module('robotsApp', ['ngRoute', 'controllers'])
.config(['$routeProvider', function($routeProvider){
var root = '/static/js/partials/';
$routeProvider.
when('/', {
templateUrl: root + 'main.html',
controller: 'main as main'
}).
when('/some-url', {
templateUrl: root + 'some_template.html',
controller: 'someController'
}).
otherwise({
redirectTo: '/'
});
}]);
angular.module('controllers', [])
.controller('main', ['$http', function($http){
$http.get('/user/recent-gain-loss').success(function(data){
this.recent_gain_loss = data;
}.bind(this));
}]);
<p>{{ main.recent_gain_loss }}</p>
Save the data in to a value and then check if the data are already set.
angular.module('values', [])
.value('recentGainLoss', {})
angular.module('controllers', ['values'])
.controller('main', ['$http', 'recentGainLoss', function($http, recentGainLoss){
if (Object.keys(recentGainLoss).length < 1) {
$http.get('/user/recent-gain-loss').success(function(data){
recentGainLoss = angular.extend(recentGainLoss, data);
});
}
this.recent_gain_loss = recentGainLoss;
}]);

AngularJS - Passing ID from a page and populate in other page

I am new to AngularJS. In my project I have a search screen when search I will get the search result in the ngGrid.
On click of any row in the grid, it should populate the details of that row in other page. Basically, I need to pass the ID of the selected record to the other page. I don't know how to handle this in AngularJS (I am using AngularJS HotTowel template) and Breeze for data access logic.
Appreciate if you could provide me link or any where it is implemented which I could refer.
You can create service and share values for instance
var myApp = angular.module('myApp', []);
myApp.factory('ShareData', function() {
var shared;
return {
setValue: function(val){
shared = val;
},
getValue: function(){
return shared;
}
});
function FirstCtrl($scope, ShareData){
ShareData.setValue(1);
}
function SecondCtrl($scope, ShareData){
$scope.data = ShareData.getValue();
}
You need $routeParams for this.
Below is an example of the routing configuration:
var app = angular.module("app", ["ngRoute"])
.config(["$routeProvider", function ($routeProvider) {
$routeProvider
.when("/", {
controller: "HomeController",
templateUrl: "/home/main",
})
.when("/products/:category", {
controller: "ProductController",
templateUrl: "/product/index"
})
.otherwise({
redirectTo: "/"
});
}]);
Product Controller
angular.module("app")
.controller("ProductController",["$scope","$routeParams", function($scope,$routeParams){
$scope.category = $routeParams.category;
alert($scope.category);
}]);
'Main' View
<a ng-href="#/products/ladies">Ladies</a>
check this URL for more info:
https://docs.angularjs.org/api/ngRoute/service/$routeParams

Can .when be dynamically generated with Angular $routeProvider?

Have an app where admins create ITEMs for users to view. Each ITEM is a doc stored in Mongo.
The item.html view and ItemController.js are consistent for all the ITEMs..
The user is first presented an ITEM_list view..
..where the user can click on an ITEM divBox,
which would reveal the item.html view populated with the specific db content found for the selected ITEM
Is there a way to have angular do something like this in appRoutes.js
angular.module('appRoutes', []).config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
$routeProvider
// start page listing all the ITEMs
.when('/', {
templateUrl: 'views/itemsList.html',
controller: 'ItemsListController'
})
// dynamic pages for each ITEM, once selected ?!
.when('/{{ITEM}}', {
templateUrl: 'views/item.html',
controller: 'ItemController'
});
$locationProvider.html5Mode(true);
}]);
You can use parameters in the route by using a colon before whatever variable name you want.
For example:
.when('/:itemID', {
templateUrl: 'views/item.html',
controller: 'ItemController'
}
Then in your ItemController, you can call that using $routeParams.
.controller('ItemController', ['$scope', '$routeParams',
function($scope, $routeParams) {
$scope.itemID = $routeParams.itemID;
}]);
Here is the link to the Angular docs for some more guidance. http://docs.angularjs.org/tutorial/step_07
You can pass the item id, for example, like so:
.when('/item/:item_id', {
templateUrl: 'views/item.html',
controller: 'ItemController'
})
Then, in your controller, you can inject $routeParams:
.controller('ItemController', function($scope, $routeParams) {
var item_id = $routeParams.item_id;
});
Then, when they select, you set the location to /item/2 or whatever, and you know it is item 2 in your controller, so you can then either fetch that item from the server, or if you have a service with them already loaded you can figure out which one it is.

Categories

Resources