从路由提供商访问控制器数据

时间:2015-10-15 19:53:34

标签: javascript angularjs

我有一个带路由器和一堆控制器的Angular应用程序,组织如

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>

现在,我想根据路径和页面内容设置<head>数据,如页面标题,meta数据等。数据显然在控制器中,因此我现在正在设置<head>数据。

不幸的是,这变得非常混乱:这里的控制器,那里的控制器,可能在同一个视图中活动,这个设置页面标题,一个设置页面标题......一个调试迷宫。

理想情况下,我想在一个地方设置元数据,上面的$routeProvider对我来说似乎很理想。不幸的是,我们无法访问那里的控制器数据。或者我们呢?

是否可以从$routeProvider

访问控制器数据

3 个答案:

答案 0 :(得分:2)

我认为你是以错误的方式解决问题。如果需要以上控制器的范围,则在实例化控制器之前应该解析。然后,您可以像注入任何组件一样在控制器中注入此数据。

特别参见resolve$routeProvider属性的documentation

以下是一个例子:

$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, ...) {
    // ...
}

除了resolve属性之外,如果你需要从api获取数据,这个属性特别有用,你也可以使用技巧:在路由的顶层定义数据定义:

$routeProvider
    .when('/phone/:phoneId', {
         controller: 'PhoneDetailController',
         templateUrl: 'phone.detail.html',
         routeMetadata: {
             title: 'Phone product page',
             keywords: ['phone', 'mobile', 'cellular']
         }
    });

然后可以在$route.current中访问此数据。虽然我写了这个,但我宁愿选择resolve属性。后者更像是一种解决方法,因为模块ngRoute自定义属性定义的属性之间的差异并不明显。

答案 1 :(得分:0)

在标题标签中定义一个变量,如

<title>{{ PageSettings.title() }}</title>

然后为它添加服务

myModule.factory('PageSettings', function() {
   var title = 'default';
   return {
     title: function() { return title; },
     setTitle: function(newTitle) { title = newTitle }
   };
});

在路线配置中,添加标题

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

答案 2 :(得分:0)

如果您必须使用

等页面的更多信息
  • 标题
  • 元数据
  • 关键字
  • 描述
  • 以及更多

然后我建议使用angularjs-viewhead

如果只有一两个信息,那么你可以在路由中设置它们,在更改路线时你可以设置它。

使用ui-router

了解我是如何实现这一目标的
.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>