【问题标题】:Angular ui router (extras) $stateChangeStart event trigger twiceAngular ui 路由器(附加)$stateChangeStart 事件触发两次
【发布时间】:2026-01-14 05:10:02
【问题描述】:

谁能解释我为什么Angular UI Router Extras加法 触发两次(在初始化时!)$stateChangeStart 事件,以防我有一些异步 ajax 检查和e.preventDefault() 调用?

短事件代码示例:

 $rootScope.$on("$stateChangeStart", function (e, toState, toParams, fromState, fromParams, error) {
       console.log("$stateChangeStart");//fired twice
       if(!User.data) {
             e.preventDefault();
             $http.get("https://randomuser.me/api/")
             .success(function(data, status, headers, config) {
                  console.log(data);
                  User.data = data; 
                  $state.go(toState, toParams);
              });
       }              
 });

Full FIDDLE Example

没有额外的东西,一切都按预期工作。

Tnx

【问题讨论】:

  • 删除e.preventDefault();
  • 那么成功回调中的状态改变永远不会执行
  • 触发一次,你阻止它,因为数据没有返回......你重定向并再次触发。在解析主应用程序状态时执行此 api 调用会更好
  • 请提供一些小提琴...

标签: javascript angularjs ajax angular-ui-router angular-ui-router-extras


【解决方案1】:

Angularjs 在其摘要周期中进行多次检查以检查更改前后的内容,这可能是该周期的一部分。

您可以在 $watch 期间看到此行为。

$scope.$watch('myVariable', function( change ){
  if( !change ){ return; }
  // do important things here.
});

在摘要的第一轮中,change 参数将以 undefined 的形式出现,直到 myVariable 设置在其他位置。一旦 myVariable 设置为 else-wear,$watch 将再次触发并突破 if 块做一些真正的工作。

如果你的函数是这种情况,也许你可以添加一个 if 块,如果你的一个或多个参数未定义,或者你没有执行某些值,则返回。

$rootScope.$on("$stateChangeStart", function (e, toState, toParams, fromState, fromParams, error) {

  if( !e || !toStateForExample || anotherParameter ){ return; }

  console.log("$stateChangeStart");//fired twice
  if(!User.data) {
    e.preventDefault();
    $http.get("https://randomuser.me/api/")
    .success(function(data, status, headers, config) {
      console.log(data);
      User.data = data; 
      $state.go(toState, toParams);
    });
   }              
 });

【讨论】:

  • 我认为必须存在更优雅的解决方案来解决这个问题。这种额外的添加有时真的很麻烦
  • 先尝试一下,看看想法是否正确,然后重构以匹配你现有的优雅。