ui-router resolve在Ionic中表现得很奇怪

时间:2014-07-24 23:36:44

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

我是从一个演示离子应用程序(ionic start myApp sidemenu),and added a resolve to one of the views

开始的
resolve: {
  issue: function($q, $timeout) {
    var defer = $q.defer();
    //defer.reject();       // Doesn't work browser or device
    $timeout(defer.reject); // Works in browser, but not device
    return defer.promise;
  }
}

我在这里监视被拒绝的resolve

.run(function($ionicPlatform, $rootScope, $ionicLoading) {
  $ionicPlatform.ready(function() {
    // regular stuff here

    $rootScope.$on('$stateChangeError', function() {
      $ionicLoading.show({
        template: 'All good!'
      });
    });
  });
});

出于某种原因,如果resolve立即拒绝(请参阅上面的defer.reject()),则不会运行$stateChangeError的回调。如果我做的完全一样,但在Ionic之外,it works!

此外,尝试通过resolve延迟$timeout(defer.reject);拒绝会导致不同的行为。现在它可以按预期在浏览器中运行,但仍然无法在设备上运行。试图延迟甚至更多,导致设备成功:

$timeout(function() {
  defer.reject();
}, 250); // Doesn't work for me with 200 or less

有人能说清楚这个吗?

SEE HERE HOW TO REPRODUCE THE ISSUE

2 个答案:

答案 0 :(得分:1)

1)$ timeout需要超过200

首先 - 我从未见过像$ timeout(deferred.reject)这样的结构;我不相信defered.reject会返回$ timeout所期望的任何函数。

我尝试了50并且它有效。 这是http://plnkr.co/edit/6NXZEXrfz3WHVqoaRYJB?p=preview 超时50或更少,但工作,所有好!打印出来。

resolve: {
              test: function($q,  $timeout) {
                var defer = $q.defer(); 
                $timeout(function(){
                  defer.reject();
                },50);
                return defer.promise; 
              }
}

这是在iconicPlatform.ready

之外的stateChangeError

2)$ stateChangeError无法正常工作

我认为这与时间有关。我不知道内部关于何时执行ionicPlatform.ready(),但我不确定它是否有必要。您的starter模块依赖于它,因此它将被加载。有时,种子项目不仅仅是种子,而是种子。

UPDATED - 在其他设备上发现了有关ready()的错误。看来ready方法没有被执行。

https://github.com/driftyco/ionic/issues/1751

答案 1 :(得分:1)

根据我对Angular和promise模型的经验。为了解决/拒绝一个承诺,Angular必须勾选JS事件循环的一个循环 - nextTick - 这可以使用$ scope.apply()完成,这就是我们在单元测试中模拟这些东西的方式。

这是一个很棒的article,讨论$ timeout和$ scope。$ evalAsync - 从我可以收集到的$ timeout正在评估下一个tick中的函数。这个代码按照您概述的方式工作的原因是什么。

resolve: {
  issue: function($q, $timeout) {
    var defer = $q.defer();
    //defer.reject();       // <---- no nextTick
    $timeout(defer.reject); // <---- $timeout evaluates on nextTick
    return defer.promise;
  }
}

这是另一个讨论$ q的textTick实现的article

我知道这并不能解决你的问题 - 但它应该解释为什么会这样!祝你好运!