Ответ 1
В CSS добавьте:
[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
display: none !important;
}
и просто добавьте атрибут ng-cloak "в ваш div, как здесь:
<div id="template1" ng-cloak>{{scoped_var}}<div>
У меня проблема в Angularjs, где в моем HTML есть мерцание, прежде чем мои данные вернутся с сервера.
Вот видео, демонстрирующее проблему: http://youtu.be/husTG3dMFOM - обратите внимание на # | и серая область справа.
Я пробовал ngCloak без каких-либо успехов (хотя ngCloak не позволяет появляться в скобках как обещано), и мне интересно, как лучше всего скрыть контент, пока HTML не будет заполнен Angular.
Я получил его для работы с этим кодом в контроллере:
var caseCtrl = function($scope, $http, $routeParams) {
$('#caseWrap').hide(); // hides when triggered using jQuery
var id = $routeParams.caseId;
$http({method: 'GET', url: '/v1/cases/' + id}).
success(function(data, status, headers, config) {
$scope.caseData = data;
$('#caseWrap').show(); // shows using jQuery after server returns data
}).
error(function(data, status, headers, config) {
console.log('getCase Error', arguments);
});
}
... но я снова и снова слышал, чтобы не манипулировать DOM с контроллера. Мой вопрос: как я могу достичь этого, используя директиву? Другими словами, как я могу скрыть элемент, к которому прикреплена директива, пока все содержимое не будет загружено с сервера?
В CSS добавьте:
[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
display: none !important;
}
и просто добавьте атрибут ng-cloak "в ваш div, как здесь:
<div id="template1" ng-cloak>{{scoped_var}}<div>
На вашем элементе caseWrap введите ng-show="contentLoaded"
, а затем, где у вас есть $('#caseWrap').show();
, поставьте $scope.contentLoaded = true;
Если элемент caseWrap находится вне этого контроллера, вы можете делать то же самое, используя $rootScope или события.
Добавьте в свой CSS следующее:
[ng\:cloak],[ng-cloak],.ng-cloak{display:none !important}
Компиляция ваших шаблонов angular не выполняется достаточно быстро.
Вам не следует выполнять манипуляции с DOM в контроллере. Есть две вещи, которые вы можете сделать...
1. Вы можете перехватывать изменения в значение в пределах объема контроллера через директиву! В вашем случае создайте директиву как атрибут, которому присвоено свойство, которое вы хотите посмотреть. В вашем случае это будет caseData
. Если casedata ложно, скройте его. В противном случае покажите его.
var myApp = angular.module('myApp', []);
myApp.controller("caseCtrl", function ($scope, $http, $routeParams, $timeout) {
$scope.caseData = null;
//mimic a delay in getting the data from $http
$timeout(function () {
$scope.caseData = 'hey!';
}, 1000);
})
.directive('showHide', function () {
return {
link: function (scope, element, attributes, controller) {
scope.$watch(attributes.showHide, function (v) {
if (v) {
element.show();
} else {
element.hide();
}
});
}
};
});
<div ng-controller='caseCtrl' show-hide='caseData'>using directive</div>
<div ng-controller='caseCtrl' ng-show='caseData'>using ngShow</div>
JSFIDDLE: http://jsfiddle.net/mac1175/zzwBS/
Поскольку вы попросили директиву, попробуйте это.
.directive('showOnLoad', function() {
return {
restrict: 'A',
link: function($scope,elem,attrs) {
elem.hide();
$scope.$on('show', function() {
elem.show();
});
}
}
});
Придерживайтесь (show-on-load) в своем элементе, а в вашем контроллере вводите $rootScope и используйте это широковещательное событие при загрузке html.
$rootScope.$broadcast('show');
Я использовал ответ Zack для создания директивы 'loading', которая может быть полезна некоторым людям.
Шаблон:
<script id="ll-loading.html" type="text/ng-template">
<div layout='column' layout-align='center center'>
<md-progress-circular md-mode="indeterminate" value="" md-diameter="52"></md-progress-circular>
</div>
</script>
Директива:
directives.directive('loading', function() {
return {
restrict: 'E',
template: 'll-loading.html',
link: function($scope,elem,attrs) {
elem.show();
$scope.$on('loaded', function() {
console.log("loaded: ");
elem.hide();
});
}
}
});
В этом примере используется angular -материал в html
Принятый ответ не помог мне. У меня были некоторые элементы, которые имели ng-show директивы, и элементы все равно отображались бы на мгновение даже с ng-cloak. Похоже, что ng-cloak был разрешен до появления ng-show false. Добавление класса ng-hide в мои элементы исправило мою проблему.