Angular JS viewContentLoaded在初始主页加载时加载两次

Ste*_*ieB 12 angularjs angular-ui-router

我注意到在我的初始主页加载时,我的viewContentLoaded发射了两次,为什么会这样?

app.run(function 
    ($rootScope,$log) {
      'use strict';
      $rootScope.$state = $state;
      $log.warn("gets here");

      $rootScope.$on('$viewContentLoaded',function(){
        $log.warn("gets here2");
      });
    });
Run Code Online (Sandbox Code Playgroud)

页面加载时的输出

"gets here" 
"gets here2" 
"gets here2"
Run Code Online (Sandbox Code Playgroud)

我的路由如下

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

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

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

我的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>
Run Code Online (Sandbox Code Playgroud)

Fun*_*One 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);
        ...
      }
    }
 }
Run Code Online (Sandbox Code Playgroud)

updateView函数

    function updateView(firstTime) {
      ...
      currentScope.$emit('$viewContentLoaded');
      currentScope.$eval(onloadExp);
    }
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请参阅GitHub上的完整源代码- viewDirective.js


Pan*_*kar 5

为什么两次接到电话?

我确定您的serach.html页面再次包含ui-view,这是在调用试图加载视图并在事件结束时$emiting进行调用$viewContentLoaded。只需ui-view在html 上呈现一定数量的呈现事件就可以$emit$viewContentLoaded


因为要确保仅将事件调用一次,然后将事件放在$ stateChangeSuccess上,这将确保在通过状态加载所有ui视图后仅将其触发一次。

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