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

dnc*_*253 96 javascript angularjs

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

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

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

jla*_*eau 129

从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:'/'});
    }
);
Run Code Online (Sandbox Code Playgroud)

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

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

  • 这在1.2中完全支持,它可能是最好的方法:http://docs.angularjs.org/api/ngRoute/provider/$routeProvider (5认同)

Glo*_*opy 84

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

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

哪个产生了这个错误:

未知的提供者:来自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';
    }
Run Code Online (Sandbox Code Playgroud)

以此作为你的 urlRouter.html

<div ng-include src="templateUrl"></div>
Run Code Online (Sandbox Code Playgroud)

  • 您实际上不必创建"单行html文件" - 只需使用"template:"键而不是"templateUrl",并为其提供包含html单行的字符串;-) (18认同)
  • 如果你将`template`设置为一个函数,你可以将`$ routeParams`传递给该函数:`$ routeProvider.when('/:pNav /:sNav',{template:fn($ routeParams){return $ routeParams.pNav +'/'+ $ routeParams.sNav +'.html'}});`.但是,您无法以这种方式动态定义控制器:( (8认同)
  • https://groups.google.com/forum/?fromgroups=#!topic/angular/qNi5lqm-Ps8记录了前者不起作用的问题.作为`config()的注入目标,只传递提供者,而不是实际的服务实例,如`$ routePrams`. (6认同)

小智 18

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

查看示例.

.when('/:screenName/list',{
    templateUrl: function(params){
         return params.screenName +'/listUI'
    }
})
Run Code Online (Sandbox Code Playgroud)

希望这有帮助.


Cod*_*ody 7

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

第一个小背景:我需要这个的原因是将Angular放在Node Express的顶部并让Jade处理我的部分内容.

所以这里有什么必须做的...(喝啤酒,先花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/');

});
...
Run Code Online (Sandbox Code Playgroud)

这可能比需要的更多信息......

  • 基本上,您需要$routeProvider全局存储Module的var,例如,routeProvider以便控制器可以访问它.

  • 然后你可以使用routeProvider并创建一个新的路由(你不能'重置一个路由'/'重新建立';你必须创建一个新的路由),我只是在末尾添加一个斜杠(/),以便它是语义的作为第一个.

  • 然后(在您的控制器内),设置templateUrl您想要点击的视图.

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

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

如果您对如何将Angular应用程序打到Express应用程序感兴趣,可以在此处分享我的回复:https://github.com/cScarlson/isomorph.

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

如果您此时克隆此内容,则需要在计算机上运行mongoDB才能运行它.

希望这能解决这个问题!

科迪

不要喝你的洗澡水.