AngularJS - How to use $routeParams in generating the templateUrl?
Solution 1:
This very helpful feature is now available starting at version 1.1.2 of AngularJS. It's considered unstable but I have used it (1.1.3) and it works fine.
Basically you can use a function to generate a templateUrl string. The function is passed the route parameters that you can use to build and return the templateUrl string.
var app = angular.module('app',[]);
app.config(
function($routeProvider) {
$routeProvider.
when('/', {templateUrl:'/home'}).
when('/users/:user_id',
{
controller:UserView,
templateUrl: function(params){ return '/users/view/' + params.user_id; }
}
).
otherwise({redirectTo:'/'});
}
);
Many thanks to https://github.com/lrlopez for the pull request.
https://github.com/angular/angular.js/pull/1524
Solution 2:
I couldn't find a way to inject and use the $routeParams
service (which I would assume would be a better solution) I tried this thinking it might work:
angular.module('myApp', []).
config(function ($routeProvider, $routeParams) {
$routeProvider.when('/:primaryNav/:secondaryNav', {
templateUrl: 'resources/angular/templates/nav/'+$routeParams.primaryNav+'/'+$routeParams.secondaryNav+'.html'
});
});
Which yielded this error:
Unknown provider: $routeParams from myApp
If something like that isn't possible you can change your templateUrl
to point to a partial HTML file that just has ng-include
and then set the URL in your controller using $routeParam
s like this:
angular.module('myApp', []).
config(function ($routeProvider) {
$routeProvider.when('/:primaryNav/:secondaryNav', {
templateUrl: 'resources/angular/templates/nav/urlRouter.html',
controller: 'RouteController'
});
});
function RouteController($scope, $routeParams) {
$scope.templateUrl = 'resources/angular/templates/nav/'+$routeParams.primaryNav+'/'+$routeParams.secondaryNav+'.html';
}
With this as your urlRouter.html
<div ng-include src="templateUrl"></div>
Solution 3:
templateUrl can be use as function with returning generated URL. We can manipulate url with passing argument which takes routeParams.
See the example.
.when('/:screenName/list',{
templateUrl: function(params){
return params.screenName +'/listUI'
}
})
Hope this help.
Solution 4:
Alright, think I got it...
Little background first: The reason I needed this was to stick Angular on top of Node Express and have Jade process my partials for me.
So here's whatchya gotta do... (drink beer and spend 20+ hours on it first!!!)...
When you set up your module, save the $routeProvider
globally:
// app.js:
var routeProvider
, app = angular.module('Isomorph', ['ngResource']).config(function($routeProvider){
routeProvider = $routeProvider;
$routeProvider
.when('/', {templateUrl: '/login', controller: 'AppCtrl'})
.when('/home', {templateUrl: '/', controller: 'AppCtrl'})
.when('/login', {templateUrl: '/login', controller: 'AppCtrl'})
.when('/SAMPLE', {templateUrl: '/SAMPLE', controller: 'SAMPLECtrl'})
.when('/map', {templateUrl: '/map', controller: 'MapCtrl'})
.when('/chat', {templateUrl: '/chat', controller: 'ChatCtrl'})
.when('/blog', {templateUrl: '/blog', controller: 'BlogCtrl'})
.when('/files', {templateUrl: '/files', controller: 'FilesCtrl'})
.when('/tasks', {templateUrl: '/tasks', controller: 'TasksCtrl'})
.when('/tasks/new', {templateUrl: '/tasks/new', controller: 'NewTaskCtrl'})
.when('/tasks/:id', {templateUrl: '/tasks', controller: 'ViewTaskCtrl'})
.when('/tasks/:id/edit', {templateUrl: '/tasks', controller: 'EditTaskCtrl'})
.when('/tasks/:id/delete', {templateUrl: '/tasks', controller: 'DeleteTaskCtrl'})
.otherwise({redirectTo: '/login'});
});
// ctrls.js
...
app.controller('EditTaskCtrl', function($scope, $routeParams, $location, $http){
var idParam = $routeParams.id;
routeProvider.when('/tasks/:id/edit/', {templateUrl: '/tasks/' + idParam + '/edit'});
$location.path('/tasks/' + idParam + '/edit/');
});
...
That may be more info than what was needed...
Basically, you'll wanna store your Module's
$routeProvider
var globally, eg asrouteProvider
so that it can be accessed by your Controllers.Then you can just use
routeProvider
and create a NEW route (you can't 'RESET a route' / 'REpromise'; you must create a new one), I just added a slash (/) at the end so that it is as semantic as the first.Then (inside your Controller), set the
templateUrl
to the view you want to hit.Take out the
controller
property of the.when()
object, lest you get an infinite request loop.And finally (still inside the Controller), use
$location.path()
to redirect to the route that was just created.
If you're interested in how to slap an Angular app onto an Express app, you can fork my repo here: https://github.com/cScarlson/isomorph.
And this method also allows for you to keep the AngularJS Bidirectional Data-Bindings in case you want to bind your HTML to your database using WebSockets: otherwise without this method, your Angular data-bindings will just output {{model.param}}
.
If you clone this at this time, you'll need mongoDB on your machine to run it.
Hope this solves this issue!
Cody
Don't drink your bathwater.
Solution 5:
Router:-
...
.when('/enquiry/:page', {
template: '<div ng-include src="templateUrl" onload="onLoad()"></div>',
controller: 'enquiryCtrl'
})
...
Controller:-
...
// template onload event
$scope.onLoad = function() {
console.log('onLoad()');
f_tcalInit(); // or other onload stuff
}
// initialize
$scope.templateUrl = 'ci_index.php/adminctrl/enquiry/'+$routeParams.page;
...
I believe it is a weakness in angularjs that $routeParams is NOT visible inside the router. A tiny enhancement would make a world of difference during implementation.