为什么$ state.go不工作时,目标状态或它的父与承诺解决它的、状态、目标、工作

2023-09-13 03:25:11 作者:欧典-The empty

我试图加载于母公司状态的一些数据与决心,当应用程序运行,像这样重定向用户到默认状态:

I tried to load some data on parent state with resolve and to redirect user to default state when the app runs like so:

app.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {

  $stateProvider.state('home', {
    url: '/',
    template: '<div><a ui-sref="home">Start App</a> <a ui-sref="home.main">Home</a> <a ui-sref="home.other">Other state</a><div ui-view>Loading...</div></div>',
    resolve: {
      user: ['$timeout', '$q', 
        function($timeout, $q) {
          var deferred = $q.defer();
          var promise = deferred.promise;
          var resolvedVal = promise.then(function() {
            console.log('$timeout executed');
            return {Id: 12, email: 'some@email.com', name: 'some name'};
          }, function() {
            console.log('Error happend');
          });
          $timeout(function() {
            deferred.resolve();
          }, 2000);
          return resolvedVal;
        }]
      //user: function() {return {id: 222, name: 'testname', email: 'test@em.ail'}; }
    },
    controller: ['$scope', 'user', function($scope, user) {
      $scope.user = user;
    }]
  });

  $stateProvider.state('home.other', {
    url: 'other',
    template: '<div>Your name is {{user.name}}, and email is {{user.email}}</div><div>This is other state of application, I try to make it open as default when application starts, by calling to $state.transitionTo() function in app.run() method</div>',
    resolve: {
      someObj: function() {
        console.log('hello');
        return {someProp: 'someValue'};
      }  
    },
    controller: ['$scope', 'user', function($scope, user) {
      $scope.user = user;
    }]    
  });

}]);  

app.run(['$state', '$rootScope', function ($state, $rootScope) {
  $state.go('home.other');   
}]);

和这并不在地址栏更改网址和(虽然执行home.state的决心功能并且在控制台'你好')不显示home.other状态的模板。但是,当我决心评论功能的承诺,而是放在那里简单的函数返回的对象应用程序重定向预期。

And this does not change url in address bar and does not show template of home.other state (though the resolve function of home.state is executed and there is 'hello' in console). But when I comment promise function in resolve and instead put there simple function returning object application redirects as expected.

此外,而不是$超时试图做到这实际上将有$ HTTP请求,但没有运气了。

Also instead of $timeout tried to do $http request which will actually be there, but no luck too.

推荐答案

和回答我的问题 - 不必要的行为happend因为消化周期的开始处理$ state.go('home.other')后,请求的URL被称为并决心函数创建递延对象,尽管该对象是解决了,状态引擎已经传递到请求的URL的状态。因此,要prevent这个我用工艺说明如下:

And to answer my own question - unwanted behavior happend because of digest cycle starts to handle requested url after $state.go('home.other') was called and as the resolve function creates deffered object, though this object is resolved, state engine already passes to the requested url's state. So to prevent this I used the technic explained below:

如果您需要放弃某些curcumstances请求的URL的状态resolvation的执行时,应用程序startes,您可以用$ stateChangeStart事件,像这样:

If you need to discard execution of requested url's state resolvation in certain curcumstances when the application startes, you can use $stateChangeStart event, like this:

app.run(['$state', '$rootScope', '$timeout', function ($state, $rootScope, $timeout) {
  var appStarted = 0; // flag to redirect only once when app is started
  $rootScope.$on('$stateChangeStart', 
  function(event, toState, toParams, fromState, fromParams) { 
    if(appStarted) return;
    appStarted = 1;   
    event.preventDefault(); //prevents from resolving requested url
    $state.go('home.other'); //redirects to 'home.other' state url
  });  
}]);