Angular UI路由器 - 默认参数

时间:2014-07-26 15:46:50

标签: angularjs angular-ui angular-ui-router

无论如何使用Angular UI路由器为每条路由指定默认参数?

通过选择用户然后导航到我的应用程序,通过其他应用程序的上下文输入我的应用程序。我的应用程序中的URL将始终在URL中具有用户ID,以便人们可以为URL添加书签,通过电子邮件发送等等。因此,当您浏览时,URL始终遵循以下方案:

#/{userId}/view/...
#/{userId}/edit/...

等。

对于他们前往的任何路线,此appId对于应用内部的用户始终是相同的。如果他们碰巧注销,请返回主应用程序,选择一个新用户并返回我的应用程序,此userId将更改,但每个路径的值将相同。

无论如何从服务/工厂读取这个值,然后将其插入每条路线?

编辑:

我应该提一下,当我导航到某个状态时,我希望避免在每个路由上显式设置此参数。例如,每次我导航到新状态时,我都不想做ui-sref="new-state({userId : blah})"。 userId永远不会在我的应用程序的上下文中更改。

再次编辑:

我实际上是以不同的方式解决了这个问题,即不必发送' userId'手动到每条路线。我没有使用指令,而是使用$ provide.decorator将此功能添加到' go'方法。我在下面的回答中添加了一个答案。

3 个答案:

答案 0 :(得分:7)

您可以声明子状态继承的抽象父状态:

$stateProvider
  .state('user', {
     url: '/:userid',
     abstract: true,
     resolve: 
       // assuming some kind of User resource factory
       currentUser: function($stateParams, User) {
         return User.get($stateParams.userid);
       }
     }
   })
  .state('user.view', {
     url: '/view', // actual url /:userid/view
     controller: function($scope, currentUser) {
       // currentUser resource available
     }
   });
  .state('user.edit', {
     url: '/edit', // actual url /:userid/edit
     controller: function($scope, currentUser) {
       // currentUser resource available
     }
   });

在导航到州时,您需要传入所需的用户:

$state.go('user.view', {userid: 'myuserid'});

因此,在currentUser服务上创建某种.go()包装器方法可能是有意义的,这样您就不必每次都指定用户ID。

<强>更新

要解决编辑中发布的问题,您可以引入如下指令:

angular.module('app')
  .directive('userSref', function($state) {               
     return function(scope, elem, attrs) {
       var state = 'user.' + attrs.userSref;

       elem.bind('click', function() {
         $state.go(state, {userid: $state.params.userid});
       });           

       scope.$on('$destroy', function() {
         elem.unbind('click');
       });
     };
  });

然后,任何将来基于用户的状态的链接都可以通过以下方式完成:

<a user-sref="view">View User</a>

答案 1 :(得分:3)

我没有编写处理userID自动发送的指令,而是使用$provide.decorator,如下所示:

app.config(['$provide',
    function($provide) {
        $provide.decorator('$state', function($delegate, UserService) {

            // Save off delegate to use 'state' locally
            var state = $delegate;

            // Save off reference to original state.go
            state.baseGo = state.go;

            // Decorate the original 'go' to always plug in the userID
            var go = function(to, params, options) {

                params.userID = UserService.userID;

                // Invoke the original go
                this.baseGo(to, params, options);
            };

            // assign new 'go', decorating the old 'go'
            state.go = go;

            return $delegate;
        });
    }
]);

我从这篇文章中得到了这个想法:

Changing the default behavior of $state.go() in ui.router to reload by default

答案 2 :(得分:-1)

您可以使用&#34;嵌套状态&#34;和&#34;解决&#34; UI-Router的功能,用于在应用中创建状态层次结构。您将定义解析userId的顶级状态。然后定义任意数量的子状态,它们将自动继承&#34;已解决的&#34; userId

查看this page of the documentation,特别是标题为&#34;重要$ stateParams Gotcha&#34;的部分。我将在此处粘贴该页面中的两个代码段。

方法不正确:

$stateProvider.state('contacts.detail', {
   url: '/contacts/:contactId',   
   controller: function($stateParams){
      $stateParams.contactId  //*** Exists! ***//
   }
}).state('contacts.detail.subitem', {
   url: '/item/:itemId', 
   controller: function($stateParams){
      $stateParams.contactId //*** Watch Out! DOESN'T EXIST!! ***//
      $stateParams.itemId //*** Exists! ***//  
   }
})

使用&#34;解决&#34;

的正确方法
$stateProvider.state('contacts.detail', {
   url: '/contacts/:contactId',   
   controller: function($stateParams){
      $stateParams.contactId  //*** Exists! ***//
   },
   resolve:{
      contactId: ['$stateParams', function($stateParams){
          return $stateParams.contactId;
      }]
   }
}).state('contacts.detail.subitem', {
   url: '/item/:itemId', 
   controller: function($stateParams, contactId){
      contactId //*** Exists! ***//
      $stateParams.itemId //*** Exists! ***//  
   }
})

自&#34; contactId&#34;参数由父状态解析,子状态将继承该状态。