Router resolve will not inject into controller

自作多情 提交于 2019-11-29 15:10:47

问题


I have tried everything to get ui-router's resolve to pass it's value to the given controller–AppCtrl. I am using dependency injection with $inject, and that seems to cause the issues. What am I missing?

Routing

$stateProvider.state('app.index', {
  url: '/me',
  templateUrl: '/includes/app/me.jade',
  controller: 'AppCtrl',
  controllerAs: 'vm',
  resolve: {
    auser: ['User', function(User) {
      return User.getUser().then(function(user) {
        return user;
      });
    }],
  }
});

Controller

appControllers.controller('AppCtrl', AppCtrl);

AppCtrl.$inject = ['$scope', '$rootScope'];

function AppCtrl($scope, $rootScope, auser) {
  var vm = this;
  console.log(auser); // undefined

  ...
}

Edit Here's a plunk http://plnkr.co/edit/PoCiEnh64hR4XM24aH33?p=preview


回答1:


When you use route resolve argument as dependency injection in the controller bound to the route, you cannot use that controller with ng-controller directive because the service provider with the name aname does not exist. It is a dynamic dependency that is injected by the router when it instantiates the controller to be bound in its respective partial view.

Also remember to return $timeout in your example, because it returns a promise otherwise your argument will get resolved with no value, same is the case if you are using $http or another service that returns a promise.

i.e

  resolve: {
    auser: ['$timeout', function($timeout) {
      return $timeout(function() {
        return {name:'me'}
      }, 1000);
    }],

In the controller inject the resolve dependency.

appControllers.controller('AppCtrl', AppCtrl);

AppCtrl.$inject = ['$scope', '$rootScope','auser']; //Inject auser here

function AppCtrl($scope, $rootScope, auser) {
  var vm = this;
  vm.user = auser;
}

in the view instead of ng-controller, use ui-view directive:

<div ui-view></div>

Demo




回答2:


Here is how I work with resolve. It should receive promise. So I create service accordingly.

app.factory('User', function($http){
    var user = {};
    return {
        resolve: function() {
            return $http.get('api/user/1').success(function(data){
                user = data;
            });
        },
        get: function() {
            return user;
        }
    }
});

This is main idea. You can also do something like this with $q

app.factory('User', function($q, $http){
    var user = {};
    var defer = $q.defer();

    $http.get('api/user/1').success(function(data){
        user = data;
        defer.resolve();
    }).error(function(){
        defer.reject();
    });

    return {
        resolve: function() {
            return defer.promise;
        },
        get: function() {
            return user;
        }
    }
});

These are almost identical in action. The difference is that in first case, service will start fetching date when you call resolve() method of service and in second example it will start fetch when factory object is created.

Now in your state.

$stateProvider.state('app.index', {
  url: '/me',
  templateUrl: '/includes/app/me.jade',
  controller: function ($scope, $rootScope, User) {
    $scope.user = User.get();
    console.log($scope.user);
  },
  controllerAs: 'vm',
  resolve: {
    auser: function(User) {
      return User.resolve()
    }
  }
});


来源:https://stackoverflow.com/questions/27914436/router-resolve-will-not-inject-into-controller

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!