问题描述
我试图向用户发送到特定的闭合状态的用户界面在使用角以下内容:
I'm attempting to send the user to a specific 'closed' UI State in Angular using the following:
$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 code>获取调用两次后,我们已经过渡到关闭状态。
The issue I'm having is that $rootScope.data = toState.data
is getting called twice AFTER we've transitioned to the 'closed' state.
在第一时间 $ startChangeStart
与 data.isClosed =导航到我们的秩序状态时执行真正
在路由器设定,状态被改变为关闭和有关的code没有得到执行。
On the first time $startChangeStart
executes when navigating to our 'order' state with data.isClosed = true
set in the router, the state is changed to 'closed' and the code in question doesn't get executed.
由于我们改变状态为关闭现在, $ startChangeStart
被再次触发,有问题的code执行首次与toState是我们关闭状态。
As we are changing states to 'closed' now, $startChangeStart
gets triggered again, and the code in question executes for the first time with toState being our 'closed' state.
奇怪的是,code为随后执行,toState是秩序的原始状态,如果()逻辑之后开始......也就是说,当一切都装起来,在$ rootScope.data变量包含从秩序,而不是封闭的数据。添加一些断点和调试code以上证实。
Strangely, the code is then subsequently executed, starting after the if() logic with toState being the original state of 'order'... meaning that when everything is loaded up, the $rootScope.data variable contains the data from 'order' rather than 'closed'. Adding a few breakpoints and the debugging code above confirms.
任何解释吗?
更新
由于与状态过渡到闭合状态的执行模式,我添加了一回,以确保 $ state.go()$ C $后继续执行C>终止呼叫。修订code:
Due to the execution pattern with the state transition to the 'closed' state, I've added a return to ensure that the continued execution after the $state.go()
call is terminated. Revised code:
$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);
});
这是现在的工作如预期,但我不知道这是正确的。
This is now working as expected, but I'm not sure it's 'correct'.
推荐答案
与return语句解决方法很简单正确的。我创建,在那里你可以测试。
The solution with return statement is simple correct. I created this playground, where you can test that.
让我们这些状态。一是一些国家与isClosed返虚假的 - 这不应该由我们的事件侦听器进行管理
Let's have these states. Firstly some state with isClosed false - which should not be managed by our event listener
.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 },
})
和这些将被捕获并重定向
and these will be caught and redirected
.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)的 - 该事件将触发一次。
Now, whenever we go to any state, the event $stateChangeStart
is fired. So if we go to "not handled" states (state1, state2) - the event will be triggered once.
如果我们去处理状态的(stateClosed1,stateClosed2)的,事件被激发两次总:
If we go to handled states (stateClosed1, stateClosed2), event is fired always twice:
- 去stateClosed1
- 去封闭
只是可以肯定:事件被解雇真正两次。这就是为什么我们应该写这些听众,而像这样的(脱身ASAP)的:
Just to be sure: the event is really fired twice. And that's why we should write these listeners rather like this (get out ASAP):
$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);
});
在实际上,这种解决方案(尽快失控),在这些问答放大器问题;答:
In fact, this solution (getting out as soon as possible), was issue in these Q & A:
- Angular ui router - Redirection doesn't work at all
- How can I fix 'Maximum call stack size exceeded' AngularJS
这篇关于$ stateChangeStart事件状态改变后继续的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!