AngularJS-如何在生成templateUrl时使用$ routeParams?


96

我们的应用程序具有2级导航。我们想使用AngularJS $routeProvider动态地向提供模板<ng-view />。我正在考虑按照以下方式做一些事情:

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

我只是不知道该如何填充<<>>。我知道primaryNav和secondaryNav绑定到$ routeParams,但是如何在这里访问$ routeParams以便动态提供模板?

Answers:


84

我找不到一种方法来注入和使用该$routeParams服务(我认为这是一个更好的解决方案),我尝试过这种想法,认为它可能会起作用:

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

产生此错误:

未知提供者:myApp中的$ routeParams

如果无法执行上述操作,则可以将其更改templateUrl为指向刚刚具有的部分HTML文件,ng-include然后使用来在控制器中设置URL,$routeParam如下所示:

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';
    }

以此为你 urlRouter.html

<div ng-include src="templateUrl"></div>

7
前者不起作用的问题已记录在groups.google.com/forum/?fromgroups=#!topic/angular/qNi5lqm-Ps8中。由于config()仅将传递目标传递给提供者,而不传递诸如的实际服务实例$routePrams
nre 2012年

18
您实际上不必创建“单行html文件”-只需使用“ template:”键而不是“ templateUrl”,并为其提供包含html
单线

1
您不能只使用template代替templateUrl吗?
kaiser

1
这实际上会起作用,但是如何为每个所选模板应用控制器呢?使用此方法将只剩下一个“主”控制器:“ RouteController”
Yaniv Efraim

9
如果您设置template为一个函数,则可以传递$routeParams给该函数:$routeProvider.when('/:pNav/:sNav', { template: fn($routeParams) { return $routeParams.pNav + '/' + $routeParams.sNav + '.html' } });。但是,您不能通过这种方式动态定义控制器:(
jacob 2014年

131

从AngularJS 1.1.2版本开始,此功能非常有用。它被认为是不稳定的,但我已经使用了它(1.1.3)并且工作正常。

基本上,您可以使用函数来生成templateUrl字符串。向该函数传递了可用于构建和返回templateUrl字符串的路由参数。

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:'/'});
    }
);

非常感谢https://github.com/lrlopez的请求请求。

https://github.com/angular/angular.js/pull/1524


5
现在已在1.2中得到完全支持,这可能是最好的方法:docs.angularjs.org/api/ngRoute/provider/$routeProvider
Stu

基于参数的动态控制器又如何呢?
2014年

请,请(请!)告诉我,这可能与controllers...有关?
科迪2014年

在这种情况下,如何从模板访问控制器(由$ routeProvider提供)?通常,如果控制器由ng-controller =“ myController”指令绑定,则可以将其myController引用为myCtrl。在这种情况下,如何定义myCtrl?
FlavorScape 2014年

@FlavorScape我也有这个问题-解决方案是执行类似$ routeProvider.when(“ / foo”,{controller:“ FooController”,controllerAs:“ foo”,templateUrl:“ foo.html”})的操作;
艾琳·德拉蒙德

18

templateUrl可以用作返回生成的URL的函数。我们可以通过带有routeParams的传递参数来操纵url。

参见示例。

.when('/:screenName/list',{
    templateUrl: function(params){
         return params.screenName +'/listUI'
    }
})

希望能有所帮助。


7

好吧,以为我明白了...

首先没有什么背景知识:我需要这样做的原因是将Angular放在Node Express之上,并让Jade为我处理我的零件。

因此,这是whatchya必须做的...(先喝啤酒,再花20多个小时!!!)...

设置模块时,请$routeProvider全局保存:

// 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/');

});
...

那可能比所需的信息更多。。。

  • 基本上,您将要$routeProvider全局存储模块的var,例如,routeProvider以便控制器可以访问它。

  • 然后,您可以使用routeProvider并创建一条新路由(您不能“重置一条路由” /“重新承诺”;您必须创建一条新路由),我只是在末尾添加了斜杠(/),以使其具有语义作为第一。

  • 然后(在Controller内)将设置为templateUrl要点击的视图。

  • 取出对象的controller属性.when(),以免获得无限的请求循环。

  • 最后(仍在Controller内),用于$location.path()重定向到刚创建的路由。

如果您对如何将Angular应用程序添加到Express应用程序感兴趣,可以在这里派发我的仓库:https : //github.com/cScarlson/isomorph

并且此方法还允许您保留AngularJS双向数据绑定,以防您想使用WebSockets将HTML绑定到数据库:否则,如果没有此方法,您的Angular数据绑定将仅输出{{model.param}}

如果此时克隆它,则需要在计算机上运行mongoDB。

希望这能解决这个问题!

科迪

不要喝你的洗澡水。


3

路由器:-

...
.when('/enquiry/:page', {
    template: '<div ng-include src="templateUrl" onload="onLoad()"></div>',
    controller: 'enquiryCtrl'
})
...

控制器:

...
// 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;
...

我相信$ routeParams在路由器内部不可见是angularjs的弱点。微小的增强将在实施过程中带来巨大变化。


3

我在我的角度叉中添加了对此的支持。它允许您指定

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

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

不确定是否会捡起它,因为它有点像棱角,但对我很有用


对!Havent已使用它,但确实需要它。还有其他需要注意的警告吗?另外,关于Angular的实现还有什么话吗?-我喜欢使用CDN。
科迪

不知道,我从来没有签署过文书工作,所以这是一个死胡同,但是您可以进行更改,并尝试将其纳入自己的工作(当我这样做时,我不再在自己所在的公司工作,他们没有进一步追求angularjs)
Jamie Pate

好的,感谢您提供的信息以及您对问题的贡献-我将在一分钟之内将其解决。
科迪2013年

1
//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;
    });

在index.html中

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

firstParam和secondParam可以根据您的需要为任意。


0

我有一个类似的问题,$stateParams而不是使用routeParam

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.