UI路由器,在服务中使用stateparams

时间:2014-01-30 09:33:44

标签: angularjs angular-ui-router

我有这个状态:

  .state('admin.category',{
    url: '/category',
    templateUrl:'views/admin.category.html',
    resolve:{
      category: ['CategoryLoader', function(CategoryLoader){
        return new CategoryLoader();
      }]
    },
  })

这是我解决的服务。

.factory('CategoryLoader',['Category', '$state', '$q',
  //console.log($state)
  function(Category, $state, $q){
    return function(){
      var delay = $q.defer();
      Category.get({cat_id:$state.params.id}, //not working
        function(category){
          delay.resolve(category);
        },
       function(){
         //delay.reject('Unable to fetch category ' + $state.params.cat_id)
      });
      return delay.promise;
    }
}]);

如果我将$ state.params.id更改为数字,那么一切正常。如果我在我的服务中安装$ state,我会得到所有内容,包括params。但我似乎无法使用它。它应该是使用$ route.current.params.id的平等,我在其他项目中使用过它。如何用ui-router做同样的事情?

更新:更多信息

家长州:

  .state('admin',{
    abstract: true,
    url: '/admin',
    templateUrl:'views/admin.html'
  })

分类工厂:

  factory('Category', function($resource){
    return $resource('/api/category/byId/:id/', {id: '@id'});
  })

如果需要,我会把小提琴放在一起

2 个答案:

答案 0 :(得分:5)

我在此处看到的问题是,您尝试在状态准备好之前访问$stateParams 。改变状态时会发生几件事。

首先是$stateChangeStart,您将收到有关您要更改和来自的状态以及两个州的所有参数的通知。

在此之后,决心开始发生。您的案例决心是调用使用$stateParams

的函数

在所有问题得到解决且良好(没有拒绝或错误)之后,以及$stateChangeSuccess事件之前,state params are updated in the $stateParams object

基本上,您无法通过$stateParams对象访问要更改的状态的参数,直到状态更改完成后 。如果状态更改被拒绝且无法更改,则执行此操作。在这种情况下,之前的状态仍然存在,之前的状态参数将位于$stateParams

作为快速解决方法,您可以使用$stateChangeStart事件访问toParams(您要更改的州的参数)并将它们放在某处($rootScope,或者服务)所以你可以在需要时访问它们。

以下是$rootScope

的简单示例
.run(['$rootScope', function($rootScope){
    $rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
        $rootScope.toParams = toParams;
    });
}]);

.factory('CategoryLoader',['$rootScope', 'Category', '$q',
  function($rootScope, Category, $q){
    return function(){
      var delay = $q.defer();
      Category.get({cat_id: $rootScope.toParams.id}, // <-- notice its using the object we put in $rootScope, not $state or $stateParams
        function(category){
          delay.resolve(category);
        },
       function(){
         //delay.reject('Unable to fetch category ' + $state.params.cat_id)
      });
      return delay.promise;
    }
}]);

此外,我认为您的资源未设置为正确使用您传递的ID。您使用上面的cat_id,为了将其链接到网址的:id,您必须将其映射为“{id:&#39; @ cat_id&#39;}

factory('Category', function($resource){
    return $resource('/api/category/byId/:id/', {id: '@cat_id'});
});

答案 1 :(得分:2)

console.log是引用和异步

更新

我查看了源代码,看起来注入解析函数的$stateParams是本地副本,而不是全局$stateParams。全局$stateParams也会在状态激活后更新。

状态网址还应包含参数:url: '/category/:id',

来自$stateParams Service docs

  

$ stateParams服务

     

如前所述, $ stateParams 服务是一个对象,每个url参数都有一个密钥。 $ stateParams 是向控制器或其他服务提供导航网址各个部分的完美方式。

     

注意: $ stateParams 服务必须指定为州控制器将作为范围   因此,只有服务对象上可以使用该状态中定义的相关参数。

所以我想你必须做这样的事情:

<强>州:

.state('admin.category',{
  url: '/category',
  templateUrl:'views/admin.category.html',
  resolve:{
    category: ['CategoryLoader','$stateParams', function(CategoryLoader, $stateParams){
      return CategoryLoader($stateParams);
    }]
  },
})

<强>工厂:

.factory('CategoryLoader',['Category', '$q',
  function(Category, $q) {
    return function($stateParams){
      var delay = $q.defer();
      Category.get({cat_id:$stateParams.id},
        function(category){
          delay.resolve(category);
        },
       function(){
         //delay.reject('Unable to fetch category ' + $stateParams.cat_id)
      });
      return delay.promise;
    }
}]);