旧状态控制器中的异步函数在新状态下执行代码

时间:2018-03-13 15:35:38

标签: angularjs angular-ui-router

我有2个州。在状态A中,我有一个异步$ http调用,在解析之后执行某些操作(比如重新加载状态)。在解析$ http之前,我转换到状态B.状态A的控制器的onDestroy事件清楚地显示在解析$ http调用之前范围被销毁并且我转换到状态B.但是,一旦原始的$ http是解析后,该函数中的代码仍然执行,重新加载状态B.

这是正常/预期的行为吗?

如果是这样,如何确保避免这种情况?

这里有一个简单的例子:https://plnkr.co/edit/G4cR9lP4cD0g1hj51T3K?p=preview。我修改了hello和关于ui-router的hello galaxy示例的组件。在hello或about状态下,单击异步按钮,它将触发包含在promise中的5s的setTimeout,并重新加载状态。在达到超时之前改变状态。该状态将被重新加载!

Hello组件:

  angular.module('hello').component('hello', {
  template: '<h3>{{$ctrl.greeting}} galaxy!</h3>' + ' <input type="button" value="Async Hello" ng-click="$ctrl.asyncBegin()">' +
  '<button ng-click="$ctrl.toggleGreeting()">toggle greeting</button> ',

  controller: function ($state) {
    this.greeting = 'hello';
    this.$onInit = async () => {

    }
    this.toggleGreeting = function () {
      this.greeting = (this.greeting == 'hello') ? 'whats up' : 'hello'
    }
    this.$onDestroy = () => {
      console.log('ENDING HELLO STATE');
    }
    this.asyncBegin = async () => {
      await new Promise((resolve, reject) => {
        setTimeout(() => {
          console.log('TIMEOUT IN HELLO');
          $state.reload();
          resolve();
        }, 5000);
      })
    }
  }
}); 

关于组件:

  angular.module('hello').component('about', {
  template: '<h3>Its the UI-Router "Hello Galaxy" app!</h3> <input type="button" value="Async About" ng-click="$ctrl.asyncBegin()">',
  controller: function ($state) {
    this.$onInit = async () => {

    }

    this.$onDestroy = () => {
      console.log('ENDING ABOUT STATE');
    }

    this.asyncBegin = async () => {
      await new Promise((resolve, reject) => {
        setTimeout(() => {
          console.log('TIMEOUT IN ABOUT');
          $state.reload();
          resolve();
        }, 5000);
      });
    }
  }
})

1 个答案:

答案 0 :(得分:2)

是的,这是预期的行为。 不,通常无法处理这个问题 - 您应该以某种方式处理每个案例。 在这个具体案例中,在this.$onDestroy方法中取消超时似乎是合乎逻辑的。

如果这种情况在您的应用中很常见,您可以编写一些服务,在某些情况下取消您的超时。(状态更改,网址更改等)