Как предотвратить показ элемента перед инициализацией AngularJS (ng-show)
В AngularJS мне интересно, как предотвратить отображение элементов на странице до того, как ng-show вступит в силу, я обнаружил, что некоторые сообщения говорят о ng-cloak, но в моем случае это не работает, вероятно, ng-cloak предназначен для предотвращения двойных фигурных скобок а не элемент стиля.
Еще один способ, о котором кто-то говорит, это определить какой-то стиль до инициализации AngularJS, но это довольно сложно управлять.
Есть ли какой-нибудь официальный способ справиться с этим?
Ответы
Ответ 1
Если вы не хотите показывать загрузчика, ng-cloak должен быть вашим решением.
Официальная документация по ng-cloak
Если у вас все еще есть проблема, вы можете попробовать добавить css, чтобы скрыть элемент с ng-cloak внутри вашего html, чтобы убедиться, что браузер имеет его вовремя.
Если вы это сделаете, выберите способ добавления ng-плаща.
Например, добавьте его как класс:
<div ng-show="condition" class="ng-cloak">...</div>
И добавьте это в свой тег html head:
<style> .ng-cloak { display: none !important; } </style>
Ответ 2
Если вы хотите просто не показывать что-либо, пока оно не будет готово к показу (некоторые данные были загружены из бэкэнда, возможно), тогда лучше использовать ng-if
. Конечно, он работает с ng-show
. Но преимущество использования ng-if
заключается в том, что вы задерживаете создание дополнительной DOM, пока оно не будет показано, и в результате вы улучшите время загрузки начальной страницы.
Вот пример:
var myApp = angular.module('myApp', []);
myApp.controller("myController", function ($scope, $timeout) {
$scope.isLoading = false;
$scope.data = null;
simAsync();
//simulate async task like http request
function simAsync() {
//loadind data has started
$scope.isLoading = true;
$timeout(function () {
$scope.data = [{
"firstname": "Sims",
"lastname": "Wilkerson"
}, {
"firstname": "Kelli",
"lastname": "Vazquez"
}, {
"firstname": "Mcdonald",
"lastname": "Byrd"
}, {
"firstname": "Taylor",
"lastname": "Frost"
}, {
"firstname": "Merle",
"lastname": "Adkins"
}, {
"firstname": "Garrett",
"lastname": "Hood"
}];
//the data has loaded
$scope.isLoading = false;
}, 1500);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myController">
</div>
Ответ 3
Используйте загрузчик, например:
JS
angular.element(document).ready(function(){
$('.loading').remove(); // Just an example dont modify the dom outside of a directive in a real app!
alert('Loaded!');
});
CSS
.loading {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #fff;
color: #000;
}
DEMO
http://codepen.io/nicholasabrams/pen/MwOMNR
Я просто ответил на аналогичную тему здесь: вкладка Angularjs Загрузка spinner при рендеринге
Ответ 4
2 варианта, чтобы полностью избежать проблемы:
<span ng-bind="expression_without_braces"></span>
Предпочтительно использовать ngBind
вместо {{ expression }}
если шаблон мгновенно отображается браузером в исходном состоянии до того, как AngularJS его скомпилирует. Поскольку ngBind
является атрибутом элемента, он делает привязки невидимыми для пользователя во время загрузки страницы.
- используйте
ui-router
для хранения HTML в отдельных файлах, которые будут загружаться/анализироваться/вставляться только при необходимости и только при инициализации контроллера.
Здесь урок hello world изменен для использования отдельного файла HTML:
// helloworld.js
var myApp = angular.module('helloworld', ['ui.router']);
myApp.config(function($stateProvider) {
var helloState = {
name: 'hello',
url: '/hello',
templateUrl: 'helloworld.html'
}
$stateProvider.state(helloState);
});
<!-- helloworld.html -->
<h3>hello world!</h3>
<!-- index.html -->
<html>
<head>
<script src="lib/angular.js"></script>
<script src="lib/angular-ui-router.js"></script>
<script src="helloworld.js"></script>
</head>
<body ng-app="helloworld">
<a ui-sref="hello" ui-sref-active="active">Hello</a>
<ui-view></ui-view>
</body>
</html>