$ stateChangeStart事件状态改变后继续 [英] $stateChangeStart event continuing after state change

查看:432
本文介绍了$ stateChangeStart事件状态改变后继续的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图向用户发送到特定的闭合状态的用户界面在使用角以下内容:

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 获取调用两次后,我们已经过渡到关闭状态。

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执行首次与t​​oState是我们关闭状态。

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()终止呼叫。修订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事件状态改变后继续的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆