Angularjs 每个控制器实例调用两次stateChangeStart事件

Angularjs 每个控制器实例调用两次stateChangeStart事件,angularjs,angular-ui-router,Angularjs,Angular Ui Router,我正在尝试在angularjs中实现一个“notifyunsavechanged”解决方案 基本上,我有一个BaseForm控制器,在那里我监听stateChangeStart事件。当我被解雇时,我会检查公司是否肮脏,当出现提示时,用户是否确认要更改位置。如果他不这样做,那么我就preventDefault()。 以下是我用来实现这一目标的代码: this.$scope.$on('$stateChangeStart', (event, toState, toParams, fromState,

我正在尝试在angularjs中实现一个“notifyunsavechanged”解决方案

基本上,我有一个
BaseForm
控制器,在那里我监听
stateChangeStart
事件。当我被解雇时,我会检查公司是否肮脏,当出现提示时,用户是否确认要更改位置。如果他不这样做,那么我就
preventDefault()
。 以下是我用来实现这一目标的代码:

this.$scope.$on('$stateChangeStart', (event, toState, toParams, fromState, fromParams) => {
        let dirtyForms = this.detailForms.filter((form) => { if (form) { return form.$dirty } });
        if (dirtyForms.length && !confirm("Are you sure to leave this page?")) {
            event.preventDefault();
        }                
});
然而,由于某种原因,如果我导航到由控制器的同一实例管理的状态,则事件会触发两次,因此会得到两次提示


为什么会这样?我怎样才能预防它呢?

我还没有尝试过,但这是我们使用的一种模式。按原样注册$stateChangeStart(为了简单起见,我缩短了它),但只需稍作修改:

const deregisterStateChangeStart =
  this.$scope.$on('$stateChangeStart', this.foo.bind(this));
我假设您在控制器的$onInit()中执行此操作。然后添加以下内容:

this.$scope.$on('$destroy', () => {
  deregisterStateChangeStart();
});

我没试过,但这是我们使用的模式。按原样注册$stateChangeStart(为了简单起见,我缩短了它),但只需稍作修改:

const deregisterStateChangeStart =
  this.$scope.$on('$stateChangeStart', this.foo.bind(this));
我假设您在控制器的$onInit()中执行此操作。然后添加以下内容:

this.$scope.$on('$destroy', () => {
  deregisterStateChangeStart();
});


你确定它是同一个实例,并且控制器没有被再次销毁和实例化吗?@FrankModica你是对的,我不确定……事实上,这可能是case@FrankModica但实际上这并没有什么意义:只有在我没有阻止default()的情况下,控制器才会被销毁和实例化。在这里,即使我是preventDefault(),事件也会触发两次。因此,如果您重新启动站点,并导航到此控制器一次,然后导航到别处并确认您想留下,下次导航时您会收到两次消息?@FrankModica go to site->navigate to controller->然后导航到别处(到同一控制器管理的url)我收到两次提示,你确定它是同一个实例,并且控制器没有被销毁并再次实例化吗?@FrankModica你是对的,我不确定……事实上,这可能是case@FrankModica但实际上这并没有什么意义:只有在我没有阻止default()的情况下,控制器才会被销毁和实例化。在这里,即使我是preventDefault(),事件也会触发两次。因此,如果您重新启动站点,并导航到此控制器一次,然后导航到别处并确认您想留下,下次导航时您会收到两次消息?@FrankModica go to site->navigate to controller->然后导航到别处(到同一控制器管理的url)我被提示了两次
this.foo.bind(this)
的目的是什么?我本来打算发布这个,但一直在等着看这是否是全部问题,因为OP说即使在第一次导航时他们也会收到两次消息。这只是为了缩短他的代码,所以我不必再把它全部写出来。唯一的变化是常量的增加。是的@FrankModica他肯定需要$destroy,否则会出现内存问题。@rrd好的,让我试试这个
this.foo.bind(this)
的目的是什么?我本来想发布这个,但正在等待看这是否是全部问题,因为OP说即使在第一次导航时,他们也会收到两次消息。这只是为了缩短他的代码,所以我不必再把它全部写出来。唯一的变化是常量的添加。是的@FrankModica他肯定需要$destroy,否则会出现内存问题。@rrd好的,让我试试这个