Как предотвратить показ элемента перед инициализацией 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>