[英]AngularJS dynamic routing
我目前有一个内置路由的AngularJS应用程序。它可以正常工作,并且一切正常。
我的app.js文件如下所示:
angular.module('myapp', ['myapp.filters', 'myapp.services', 'myapp.directives']).
config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/', { templateUrl: '/pages/home.html', controller: HomeController });
$routeProvider.when('/about', { templateUrl: '/pages/about.html', controller: AboutController });
$routeProvider.when('/privacy', { templateUrl: '/pages/privacy.html', controller: AboutController });
$routeProvider.when('/terms', { templateUrl: '/pages/terms.html', controller: AboutController });
$routeProvider.otherwise({ redirectTo: '/' });
}]);
我的应用程序内置了CMS,您可以在其中复制和添加/ pages目录中的新html文件。
即使对于新动态添加的文件,我仍然希望通过路由提供程序。
在理想的情况下,路由模式为:
$ routeProvider.when('/ pagename ',{templateUrl:'/ pages / pagename .html',控制器:CMSController});
因此,如果我的新页面名称是“ contact.html”,我希望angular选择“ / contact”并重定向到“ /pages/contact.html”。
这有可能吗? 如果是这样怎么办?
更新资料
我现在在我的路由配置中有这个:
$routeProvider.when('/page/:name', { templateUrl: '/pages/home.html', controller: CMSController })
在我的CMSController中:
function CMSController($scope, $route, $routeParams) {
$route.current.templateUrl = '/pages/' + $routeParams.name + ".html";
alert($route.current.templateUrl);
}
CMSController.$inject = ['$scope', '$route', '$routeParams'];
这会将当前templateUrl设置为正确的值。
但是,我现在想用新的templateUrl值更改ng-view 。 这是如何完成的?
angular.module('myapp', ['myapp.filters', 'myapp.services', 'myapp.directives']).
config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/page/:name*', {
templateUrl: function(urlattr){
return '/pages/' + urlattr.name + '.html';
},
controller: 'CMSController'
});
}
]);
从文档(1.3.0):
“如果templateUrl是一个函数,则将使用以下参数调用它:
{Array。}-通过应用当前路线从当前$ location.path()中提取的路线参数”
也
when(path,route):方法
- path可以包含以冒号开头并以星号结尾的命名组:例如:name *。 当路由匹配时,所有字符都以给定名称急切地存储在$ routeParams中。
好,解决了。
将解决方案添加到GitHub - http://gregorypratt.github.com/AngularDynamicRouting
在我的app.js路由配置中:
$routeProvider.when('/pages/:name', {
templateUrl: '/pages/home.html',
controller: CMSController
});
然后在我的CMS控制器中:
function CMSController($scope, $route, $routeParams) {
$route.current.templateUrl = '/pages/' + $routeParams.name + ".html";
$.get($route.current.templateUrl, function (data) {
$scope.$apply(function () {
$('#views').html($compile(data)($scope));
});
});
...
}
CMSController.$inject = ['$scope', '$route', '$routeParams'];
以#views为我的<div id="views" ng-view></div>
因此,现在它可以与标准路由和动态路由一起使用。
为了测试它,我复制了about.html文件,称为Portfolio.html,更改了其中的一些内容,并在浏览器中输入了/#/pages/portfolio
,然后显示了presto Portfolio.html。
更新将 $ apply和$ compile添加到html,以便可以注入动态内容。
我认为最简单的方法是稍后解析路由,例如,可以通过json询问路由。 确认我在配置阶段通过$ provide在$ routeProvider之外建立了工厂,这样我就可以在运行阶段甚至在控制器中继续使用$ routeProvider对象。
'use strict';
angular.module('myapp', []).config(function($provide, $routeProvider) {
$provide.factory('$routeProvider', function () {
return $routeProvider;
});
}).run(function($routeProvider, $http) {
$routeProvider.when('/', {
templateUrl: 'views/main.html',
controller: 'MainCtrl'
}).otherwise({
redirectTo: '/'
});
$http.get('/dynamic-routes.json').success(function(data) {
$routeProvider.when('/', {
templateUrl: 'views/main.html',
controller: 'MainCtrl'
});
// you might need to call $route.reload() if the route changed
$route.reload();
});
});
在$ routeProvider URI模式中,您可以指定变量参数,例如: $routeProvider.when('/page/:pageNumber' ...
,然后通过$ routeParams在控制器中访问它。
$ route页面末尾有一个很好的例子: http : //docs.angularjs.org/api/ng.$route
编辑(针对已编辑的问题):
不幸的是,路由系统非常有限-有关此主题的讨论很多,并且已经提出了一些解决方案,即通过创建多个命名视图等。但是,现在,ngView指令在每个路由上仅提供一个视图,一对一的基础。 您可以通过多种方式进行操作-更简单的方法是将视图的模板用作加载器,并在其中添加<ng-include src="myTemplateUrl"></ng-include>
标签($ scope.myTemplateUrl在控制器中创建)。
我使用了一个更复杂的解决方案(但对于更大型和更复杂的问题更清洁),基本上完全跳过了$ route服务,在这里进行详细介绍:
不确定为什么这样可行,但是在角度1.2.0-rc.2中可以使用动态(或通配符)路由...
http://code.angularjs.org/1.2.0-rc.2/angular.min.js
http://code.angularjs.org/1.2.0-rc.2/angular-route.min.js
angular.module('yadda', [
'ngRoute'
]).
config(function ($routeProvider, $locationProvider) {
$routeProvider.
when('/:a', {
template: '<div ng-include="templateUrl">Loading...</div>',
controller: 'DynamicController'
}).
controller('DynamicController', function ($scope, $routeParams) {
console.log($routeParams);
$scope.templateUrl = 'partials/' + $routeParams.a;
}).
example.com/foo->局部加载“ foo”
example.com/bar->局部加载“ bar”
无需在ng-view中进行任何调整。 '/:a'是我发现的唯一一个可以达到此目的的变量。.'/:foo'无效,除非您的部分都是foo1,foo2等...'/:a'可以与任何部分一起使用名称。
所有值都会触发动态控制器-因此没有“否则”的情况,但是,我认为这是您在动态或通配符路由方案中需要的。
从AngularJS 1.1.3开始,您现在可以使用新的catch-all参数完全执行所需的操作。
https://github.com/angular/angular.js/commit/7eafbb98c64c0dc079d7d3ec589f1270b7f6fea5
从提交:
这允许routeProvider接受与子字符串匹配的参数,即使它们包含斜杠(即使它们以星号而不是冒号作为前缀)也是如此。 例如,诸如
edit/color/:color/largecode/*largecode
将与此http://appdomain.com/edit/color/brown/largecode/code/with/slashs
匹配。
我自己(使用1.1.5)对其进行了测试,并且效果很好。 请记住,每个新URL都会重新加载您的控制器,因此,要保持任何状态,您可能需要使用自定义服务。
这是另一个效果很好的解决方案。
(function() {
'use strict';
angular.module('cms').config(route);
route.$inject = ['$routeProvider'];
function route($routeProvider) {
$routeProvider
.when('/:section', {
templateUrl: buildPath
})
.when('/:section/:page', {
templateUrl: buildPath
})
.when('/:section/:page/:task', {
templateUrl: buildPath
});
}
function buildPath(path) {
var layout = 'layout';
angular.forEach(path, function(value) {
value = value.charAt(0).toUpperCase() + value.substring(1);
layout += value;
});
layout += '.tpl';
return 'client/app/layouts/' + layout;
}
})();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.