来自路由提供程序的访问控制器数据

Access controller data from route provider

本文关键字:访问 访问控制 控制器 数据 程序 路由      更新时间:2023-09-26

我有一个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访问控制器数据?

我认为你处理这个问题的方法不对。如果该数据需要在控制器的范围之上,则应该在控制器实例化之前解析。然后你可以像注入任何组件一样将这些数据注入到控制器中。

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

除了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定义的属性与自定义属性之间的差异并不明显。

如果你需要在

    标题
  • 元数据
  • <
  • 关键字/gh>
  • 和更多

那么我建议使用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>

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

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

然后为它添加一个服务

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

在路由配置中,添加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);
}