Angular JS viewContentLoaded загрузка дважды при начальной загрузке главной страницы
Я заметил, что при загрузке моей начальной страницы мой 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'
})
Мой индекс .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>
Ответы
Ответ 1
Это просто спецификация реализации директивы uiView. Он запускает событие $viewContentLoaded во время фазы инициализации (ссылки). На этом этапе пока неизвестно, но событие все еще запущено.
И после того, как событие будет запущено снова, как только служба $state действительно разрешит ваше домашнее состояние, перейдет в него, загрузит шаблоны и т.д.
Итак, чтобы подвести итог, это происходит не из-за плохой конфигурации, а из-за того, что ваши шаблоны загружаются дважды. Это просто, как работает 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
Ответ 2
Почему он получает вызов дважды?
Я уверен, что ваша страница serach.html
снова содержит ui-view
, которая вызывает попытку загрузить представление и в конце $emiting
событие $viewContentLoaded
. Просто так много числа ui-view
, отображаемых на html, что, несомненно, будет $emit
событием $viewContentLoaded
.
Как вы хотите, чтобы ваше событие получало вызов только один раз, вы должны поместить событие в $stateChangeSuccess, который будет гарантировать, что он будет запущен только один раз после того, как все ui-представления будут загружены через состояние.
код
$rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams){
///...code here
});
Ответ 3
Это может произойти, когда 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>