12

I noticed that on my initial homepage load, my viewContentLoaded is firing twice, why is that ?

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

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

Output on page load

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

And my routing as follows

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

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

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

My 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>
3
  • How many ui-view do you have ? Commented Jun 23, 2015 at 10:38
  • Just one, added above Commented Jun 23, 2015 at 11:04
  • How many XHR Requests do you have in your console? Commented Jun 25, 2015 at 11:20

3 Answers 3

15
+100

It is just specifics of uiView directive implementation. It fires the $viewContentLoaded event during initialization (link) phase. At this point no state is yet known, but the event is still fired.

And then after the event is fired again once the $state service actually resolves your home state, makes transition into it, loads templates etc.

So to sum up, it happens not because of bad configuration nor your templates are loaded twice. It's just how uiView works.

You can even verify it by completely commenting out your state definitions and most of your index.html contents (except for ui-view itself). The $viewContentLoaded will still be fired once.

Source code excerpts:

uiView directive declaration:

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

and the updateView function

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

For more information see complete source code on GitHub - viewDirective.js

Sign up to request clarification or add additional context in comments.

Comments

5

Why it is getting call twice?

I'm sure that your serach.html page has again contain a ui-view, that is calling trying to load a view and at the end $emiting the $viewContentLoaded event. Simply As many number of ui-view rendered on the html that will surely $emit the $viewContentLoaded event.


As you want to make sure your event should be get call only once then you should put event on $stateChangeSuccess which will ensure that it will get fired only once after all the ui-views gets loaded via state.

Code

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

Comments

0

It can be happen when SearchCtrl will be called twice.

e.g.

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

and in 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>  

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.