Javascript 从路由提供程序访问控制器数据
我有一个有角度的应用程序,有一个路由器和一堆控制器,像Javascript 从路由提供程序访问控制器数据,javascript,angularjs,Javascript,Angularjs,我有一个有角度的应用程序,有一个路由器和一堆控制器,像 articleApp.config(['$routeProvider', function($routeProvider) { $routeProvider. when('/articles', { templateUrl: 'templates/articles/index.html' }). when('/articles/:articleId', { te
articleApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/articles', {
templateUrl: 'templates/articles/index.html'
}).
when('/articles/:articleId', {
templateUrl: 'templates/articles/article.html'
}).
otherwise({
redirectTo: '/articles'
});
}]);
模板中给出了控制器,例如:
<div ng-controller="ArticleCtrl">
<!-- [...] -->
</div>
现在,我想根据页面的路径和内容设置
数据,如页面标题、meta
数据等。数据显然在控制器中,因此我现在正在设置
数据
不幸的是,这变得非常混乱:这里有一个控制器,那里有一个控制器,可能在同一个视图中处于活动状态,这个控制器设置页面标题,那个控制器设置页面标题。。。调试迷宫
理想情况下,我只想在一个地方设置元数据,上面的$routeProvider
对我来说似乎很理想。不幸的是,我们无法访问那里控制器的数据。还是我们
是否可以从
$routeProvider
访问控制器数据?在标题标签中定义一个变量,如
<title>{{ PageSettings.title() }}</title>
在路线配置中,添加标题
articleApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/articles', {
templateUrl: 'templates/articles/index.html',
title: 'Articles'
}).
when('/articles/:articleId', {
templateUrl: 'templates/articles/article.html',
title: 'Article'
}).
otherwise({
redirectTo: '/articles'
});
}]);
然后你可以这样写你的控制器
function MainCtrl($scope, $route, PageSettings) {
PageSettings.setTitle($route.current.title);
}
如果您必须为页面使用更多信息,如
- 头衔
- 元数据
- 关键词
- 描述
- 还有更多
ui路由器实现的
.state('permission', {
title: 'Permission',
url: '/permission',
templateUrl: 'app/views/permission.html',
controller: 'permissionCtrl',
data: {
Roles: [Constants.Roles.admin, Constants.Roles.analyst]
}
})
.state('products', {
title: 'products Page',
url: '/products',
templateUrl: 'app/views/products.html'
});
关于改变路线的建议
app.run(['$rootScope', '$state', function ($rootScope, $state) {
$rootScope.$on('$stateChangeStart', function (event, next) {
// Page Title
$rootScope.title = next.title;
});
}]))
在Html中
<title ng-bind="title"></title>
我认为你解决问题的方法不对。如果需要的数据超出控制器的范围,则应在实例化控制器之前解决该数据。然后,您将以注入任何组件的相同方式将此数据注入控制器
有关$routeProvider
上的resolve
属性,请特别参阅
以下是一个例子:
$routeProvider
.when('/phone/:phoneId', {
controller: 'PhoneDetailController',
templateUrl: 'phone.detail.html',
resolve: {
routeMetadata: function () {
return {
title: 'Phone product page',
keywords: ['phone', 'mobile', 'cellular']
}
}
}
});
在控制器中,只需注入routeMetadata
:
app.controller('PhoneDetailController', function (..., routeMetadata, ...) {
// ...
}
除了需要从api获取数据时特别有用的resolve
属性外,还可以使用一个技巧:在路由定义的顶层定义数据:
$routeProvider
.when('/phone/:phoneId', {
controller: 'PhoneDetailController',
templateUrl: 'phone.detail.html',
routeMetadata: {
title: 'Phone product page',
keywords: ['phone', 'mobile', 'cellular']
}
});
然后可在$route.current
中访问此数据。虽然我写了这篇文章,但我更愿意使用resolve
属性。后者更像是一种解决方法,因为模块ngRoute
定义的属性与自定义属性之间的差异并不明显。感谢@Meeh的这一想法。但我不明白这是如何解决问题的。我仍然将所有setTitle
分散在控制器上,而我更愿意从$routeProvider
调用setTitle
。如何在路由时设置它?我需要从各个控制器获取信息进行设置,例如页面标题。如何在$routeProvider
中访问控制器数据?不客气。我添加了一些示例代码,可能对某些人有用。我还可以从$route.current
访问resolve
d数据吗?是的,可以从$route.current
访问resolve
属性,尽管这不是访问它的常用方式。顺便说一句,current
属性似乎是在$route
上定义的,前提是您在类似routeChangeStart
的事件上设置了侦听器。这就是我们计划使用它的方式。基本上,有一个服务监听routeChangeStart
,从$route.current
获取属性,并使用它设置页面元数据。我来试一试。
$routeProvider
.when('/phone/:phoneId', {
controller: 'PhoneDetailController',
templateUrl: 'phone.detail.html',
routeMetadata: {
title: 'Phone product page',
keywords: ['phone', 'mobile', 'cellular']
}
});