angularjs - when - ui router controlleras



UIルータ、サービス中のstateparamsを使用する (2)

私はこの状態です:

  .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を数値に変更するとすべて動作します。 私のサービスで$状態をコンソール化すれば、私は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'});
  })

私は必要ならばフィドルをまとめる

https://ffff65535.com


私がここに見ている問題は、状態が整う前に $stateParams アクセスしようとしていることです。 状態を変更するときに起こるいくつかのイベントがあります。

最初は$stateChangeStartここでは、両方の状態にあるすべてのパラメータだけでなく、すべてのパラメータに変更が加えられた状態が通知されます。

その後、解決が始まります。 あなたの場合の解決策は、 $stateParamsを使用する関数を呼び出すこと$stateParams

すべてが解決され、 $stateParams (拒否またはエラーなし)で、 $stateChangeSuccessイベントの直前に、 $stateParams$stateParamsオブジェクトで更新されます

基本的には、状態の変更が完了するまで、 $stateParamsオブジェクトを介して変更する状態の$stateParamsアクセスすることはできません。 これは、状態の変更が拒否され、変更できない場合に実行されます。 この場合、前の状態は残り、前の状態の$stateParams$stateParamsます。

簡単な回避策として、 $stateChangeStartイベントを使用してtoParams (あなたが変更しようとしている状態のtoParams )にアクセスし、それらをどこかに置くことができます( $rootScope 、またはサービス)。 。

$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を使用してcat_id場合、それをURLの:idにリンクするには、それを `{id: '@cat_id'}としてマップする必要があります

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

console.logは参照および非同期によるものです

更新

私はソースコードを見て、それは$stateParamsような解決関数に注入されてローカルコピーではなく、グローバル$stateParamsです。 グローバル$stateParamsは、状態がアクティブになった後にのみ更新されます。

州URLには、 url: '/category/:id',というパラメータも含める必要があります。

$ stateParamsからサービスドキュメント

$ stateParamsサービス

前に見たように、 $ stateParamsサービスは、urlパラメータごとに1つのキーを持つオブジェクトです。 $ stateParamsは、コントローラや他のサービスにナビゲートされたURLの個々の部分を提供するのに最適な方法です。

注意: $ 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;
    }
}]);




angular-ui-router