我试图将用户发送到特定的“关闭”状态。 Angular中的UI状态使用以下内容:
$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {
// check the destination is active
if(toState.data.isClosed) { // note that the 'closed' state has isClosed set to false
event.preventDefault();
$state.go('closed');
}
$rootScope.data = toState.data; // getting executed twice after our state transition to 'closed'
$log.debug(toState);
});
我遇到的问题是$rootScope.data = toState.data
在我们过渡到“关闭”状态后被调用两次。州。
导航到我们的订单时第一次执行$startChangeStart
&#39}在路由器中设置data.isClosed = true
的状态,状态将更改为“已关闭”状态。并且有问题的代码没有被执行。
因为我们正在改变状态以关闭'现在,$startChangeStart
再次被触发,并且有问题的代码第一次执行,而toState是我们关闭的'州。
奇怪的是,随后执行代码,从if()逻辑开始,toState是原始状态' order' ...意味着当所有内容都被加载时,$ rootScope.data变量包含来自' order'的数据。而不是关闭'。添加一些断点和上面的调试代码就可以确认。
有任何解释吗?
更新
由于执行模式状态转换为“关闭”状态。状态,我已添加一个返回以确保$state.go()
呼叫终止后继续执行。修改后的代码:
$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {
// check the destination is active
if(toState.data.isClosed) { // note that the 'closed' state has isClosed set to false
event.preventDefault();
$state.go('closed');
return;
}
$rootScope.data = toState.data; // getting executed twice after our state transition to 'closed'
$log.debug(toState);
});
现在按预期工作,但我不确定它是否正确#。
答案 0 :(得分:2)
带有return语句的解决方案很简单。我创建了this playground,您可以在那里测试它。
让我们拥有这些状态。首先是一些isClosed为false的状态 - 不应该由我们的事件监听器管理
.state('state1', {
url: "/state1",
template: "<div>this is a state1</div>",
data: { isClosed : false },
})
.state('state2', {
url: "/state2",
template: "<div>this is a state2</div>",
data: { isClosed : false },
})
这些将被捕获并重定向
.state('stateClosed1', {
url: "/stateClosed1",
template: "<div>this is a stateClosed1</div>",
data: { isClosed : true },
})
.state('stateClosed2', {
url: "/stateClosed2",
template: "<div>this is a stateClosed2</div>",
data: { isClosed : true },
})
// even this would be handy
.state('closed', {
url: "/closed",
template: "<div>this is a closed</div>",
data: { isClosed : false },
})
现在,无论何时我们前往任何州,都会触发 $stateChangeStart
事件。因此,如果我们进入“未处理”状态(state1,state2) - 事件将被触发一次。
如果我们去处理状态(stateClosed1,stateClosed2),事件总是被触发两次:
只是为了确定:事件真的被解雇了两次。这就是为什么我们应该写这些听众而不是像(尽快离开):
$rootScope.$on('$stateChangeStart', function(event, toState, toParams
, fromState, fromParams) {
// get out if we already go to state, which is about to be handled below
if(toState.name === "closed") {
return;
}
// check the destination is active
if (toState.data.isClosed) { // note that the 'closed'
event.preventDefault(); // state has isClosed set to false
$state.go('closed');
return;
}
$rootScope.data = toState.data; // getting executed 'closed'
// twice after our state transition to
// only if above if does not contain return
console.debug(toState);
});
事实上,这个解决方案(尽快退出)是这些Q&amp;答: