我有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);
});
}
}
})
答案 0 :(得分:2)
是的,这是预期的行为。
不,通常无法处理这个问题 - 您应该以某种方式处理每个案例。
在这个具体案例中,在this.$onDestroy
方法中取消超时似乎是合乎逻辑的。
如果这种情况在您的应用中很常见,您可以编写一些服务,在某些情况下取消您的超时。(状态更改,网址更改等)