如何在 AngularJS 初始化之前防止元素显示(ng-show)

How to prevent element show before AngularJS initialized( ng-show )

在AngularJS中,我想知道如何在ng-show生效之前阻止页面显示的元素,我发现一些帖子谈论ng-cloak,但它似乎对我来说不起作用,可能是ng-cloak 是为了防止双花括号而不是元素样式。

有人谈论的另一种方式是在 AngularJS 初始化之前定义一些样式,但这有点难以管理。

是否有一些官方的方法来处理这个问题?

使用这样的加载程序:

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;
}

演示

http://codepen.io/nicholasabrams/pen/MwOMNR

我刚刚在这里回答了一个类似的话题:

除非你想展示一个加载器,否则 ng-cloak 应该是你的解决方案。

Official documentation on ng-cloak

如果问题仍然存在,您可以尝试在 html 中添加 css 以使用 ng-cloak 隐藏元素,以确保浏览器及时拥有它。

如果这样做,请选择添加 ng-cloak 的方式。 例如将其添加为 class:

<div ng-show="condition" class="ng-cloak">...</div>

并将其添加到您的 html head 标签中:

<style> .ng-cloak { display: none !important; } </style>

如果您只想在准备好显示之前避免显示某些内容(可能已经从后端加载了一些数据),那么最好使用 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>

2个完全避免问题的替代方案:

<span ng-bind="expression_without_braces"></span>

It is preferable to use ngBind instead of {{ expression }} if a template is momentarily displayed by the browser in its raw state before AngularJS compiles it. Since ngBind is an element attribute, it makes the bindings invisible to the user while the page is loading.

  • 使用 ui-router 将 HTML 保存在单独的文件中,这将是 loaded/parsed/injected 仅在需要时且仅在控制器初始化时。

这里是 hello world tutorial 修改为使用单独的 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>

Angular 现在支持 ng-cloak。它已被定义为 class 和指令:

我像这样使用它作为指令:

    <div ng-show="condition" ng-cloak>...</div>

您也可以像这样使用它作为 class:

   <div ng-show="condition" class="ng-cloak">...</div>

只需在服务器端模板中使用属性 ng-cloak oninit 你的 AngularJs 控制器

<div class="right_col col-md-9" role="main" data-ng-controller="SearchController as v"
 ng-init="v.init('<?= $catalog['id'] ?>')" ng-cloak>