AngularJS - How to use $routeParams in generating

2019-01-01 06:42发布

问题:

Our application has 2-level navigating. We want to use AngularJS $routeProvider to dynamically provide templates to an <ng-view />. I was thinking of doing something along the lines of this:

angular.module(\'myApp\', []).
config([\'$routeProvider\', function($routeProvider) {
    $routeProvider.when(\'/:primaryNav/:secondaryNav\', {
        templateUrl: \'resources/angular/templates/nav/\'+<<primaryNavHere>>+\'/\'+<<secondaryNavHere>>+\'.html\'
    });
}]);

I just don\'t know how to populate the parts within the <<>>. I know the primaryNav and secondaryNav get bound to the $routeParams, but how do I access $routeParams here in order to dynamically serve up the template?

回答1:

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 $routeParams 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>


回答2:

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



回答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.



回答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 as routeProvider 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.



回答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.



回答6:

I\'ve added support for this in my fork of angular. It allows you to specify

$routeProvider
    .when(\'/:some/:param/:filled/:url\', {
          templateUrl:\'/:some/:param/:filled/template.ng.html\'
     });

https://github.com/jamie-pate/angular.js/commit/dc9be174af2f6e8d55b798209dfb9235f390b934

not sure this will get picked up as it is kind of against the grain for angular, but it is useful to me



回答7:

//module dependent on ngRoute  
 var app=angular.module(\"myApp\",[\'ngRoute\']);
    //spa-Route Config file
    app.config(function($routeProvider,$locationProvider){
          $locationProvider.hashPrefix(\'\');
          $routeProvider
            .when(\'/\',{template:\'HOME\'})
            .when(\'/about/:paramOne/:paramTwo\',{template:\'ABOUT\',controller:\'aboutCtrl\'})
            .otherwise({template:\'Not Found\'});
    }
   //aboutUs controller 
    app.controller(\'aboutCtrl\',function($routeParams){
          $scope.paramOnePrint=$routeParams.paramOne;
          $scope.paramTwoPrint=$routeParams.paramTwo;
    });

in index.html

<a ng-href=\"#/about/firstParam/secondParam\">About</a>

firstParam and secondParam can be anything according to your needs.



回答8:

I was having a similar issue and used $stateParams instead of routeParam