Angular JS视图在首页初始加载时会重复加载两次viewContentLoaded。

12
我注意到在初始加载主页时,我的viewContentLoaded事件会触发两次,为什么会这样?
app.run(function 
    ($rootScope,$log) {
      'use strict';
      $rootScope.$state = $state;
      $log.warn("gets here");

      $rootScope.$on('$viewContentLoaded',function(){
        $log.warn("gets here2");
      });
    });

页面加载时的输出

"gets here" 
"gets here2" 
"gets here2"

以下是我的路由设置

$urlRouterProvider.when('', '/');

  // For any unmatched url, send to 404
  $urlRouterProvider.otherwise('/404');

  $stateProvider
    .state('home', {
      url: '/',
      templateUrl: 'views/search.html',
      controller: 'SearchCtrl'
    })

我的Index.html

  <div id="canvas">
    <ng-include src="'views/partials/header.html'"></ng-include>
    <!-- container -->
    <div ui-view ></div>
    <!-- /container -->
    <ng-include src="'views/partials/footer.html'"></ng-include>
  </div>

你有多少个ui-view? - squiroid
只有一个,已添加在上方。 - StevieB
你的控制台中有多少个XHR请求? - Razvan B.
3个回答

15

这只是uiView指令实现的具体细节。它在初始化(链接)阶段触发$viewContentLoaded事件。此时还不知道任何状态,但事件仍然会被触发。

而当$state服务实际解析您的home状态,进入该状态,加载模板等后,事件再次被触发。

因此,总结一下,这不是由于错误的配置或模板加载两次造成的。这就是uiView的工作原理。

您甚至可以通过完全注释掉状态定义和大部分index.html内容(除了ui-view本身)来验证它。 $viewContentLoaded仍将被触发一次。

源代码摘录:

uiView指令声明:

{
    restrict: 'ECA',
    terminal: true,
    priority: 400,
    transclude: 'element',
    compile: function (tElement, tAttrs, $transclude) {
      return function (scope, $element, attrs) {
        ...
        updateView(true);
        ...
      }
    }
 }

updateView函数

    function updateView(firstTime) {
      ...
      currentScope.$emit('$viewContentLoaded');
      currentScope.$eval(onloadExp);
    }

更多信息请参见在GitHub上的完整源代码-viewDirective.js


5

为什么会被调用两次?

我确定你的 serach.html 页面中再次包含了一个 ui-view,它试图加载视图并在最后通过 $emit 触发 $viewContentLoaded 事件。简单来说,只要在 html 上渲染了多个 ui-view,就一定会触发 $emit 事件。


如果你想确保事件只被触发一次,那么你应该将事件放在 $stateChangeSuccess 上,这样可以确保在所有的 ui-views 通过状态加载后只触发一次。

代码

$rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams){ 
   ///...code here 
});

0

SearchCtrl被调用两次时,可能会发生这种情况。

例如:

$stateProvider
    .state('home', {
      url: '/',
      templateUrl: 'views/search.html',
      controller: 'SearchCtrl'
    })

并且在 index.html

<body ng-controller="SearchCtrl">
    <div id="canvas">
    <ng-include src="'views/partials/header.html'"></ng-include>
    <!-- container -->
    <div ui-view ></div>
    <!-- /container -->
    <ng-include src="'views/partials/footer.html'"></ng-include>
  </div>
</body>  

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接