使用 angularjs 和 requirejs 时的指令渲染延迟

Directive rendering delay when using angularjs and requirejs

基本上,我的问题是 "I am {{ 10 + 13 }}" 是在 main.js 中创建 "store" 模块之前每秒 second/half 渲染的内容。

<!DOCTYPE html>
<html lang="en" ng-app="store">
    <head>
        <title>...</title>
        <script data-main="main.js" src="../bower_components/requirejs/require.js"></script>
        <link href="../bower_components/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
    I am {{ 10 + 13 }}
</body>

main.js 设置 requirejs 配置,需要 angular 库并设置 "store" 模块:

require.config({
    paths: {angular: '../bower_components/angular/angular.min'},
    shim: {angular: {exports: 'angular'}}
});

require(['angular'], function(angular) {
    var app = angular.module('store', []);
});

我认为发生这种情况的原因是因为 main.js 和 angular 库被 requirejs 异步加载(在脚本标签上有一个 "async" 属性),所以DOM 在商店模块创建之前渲染,因此造成延迟。

我必须怎么做才能避免渲染 "I am {{ 10 + 13 }}" 和 "I am 13" 之间出现的这种差距?我可以加载 main.js 和 angular js synchronous/without requirejs,但这似乎不是最佳实践。

我认为你可以使用 ng-cloack 指令

<body>
    I am <span ng-cloak>{{ 10 + 13 }}</span>
</body>

添加css

[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
    display: none !important;
}

没测试过可以试试。 :)

Example

更新

隐藏 <body> 直到 angular 可用。

.initial-hide {
   display: none;
}

.show {
    display: block !important;
}


<body class="initial-hide" ng-class="{show : initedScripts}">
    ......
    ......
</body>

body 将得到 initial-hide 并隐藏,直到 show class 应用于它。当变量 initedScripts 设置为 true.

时应用 show class

JS

var app = angular.module('plunker', []);

app.run(function($rootScope) {
     $rootScope.initedScripts = true;
});

set `initedScripts` to `true` in the run block and that means angular loaded successfully.

这是一个DEMO

我添加了 2 秒超时以延迟 requirJs

对 angularjs 的调用

您可以将要插入的表达式包裹在 angular 支持的一些自定义标签中。因此,在 angular 加载并编译您页面上的所有内容之前,浏览器不会呈现它们。

选择哪一个取决于您的实际标记。 您甚至可以将其包装在自定义指令中

如@K.Toress 所述,解决此问题的方法是在 body 元素上使用 ng-cloak,或者更具体地说,在有问题的元素上使用 ng-cloak 来改善页面的呈现。

需要一些 css/style 来将 ng-cloak 元素放入 display: none;,所以如果你在 CSP 模式下使用 angular,你不会有问题,因为 angular-csp.css 样式表通常会包含在内。但是,如果您没有在 CSP 模式下使用 angular,则 angular.js/angular.min.js 中嵌入的 css 规则不会有任何效果,因为库很可能会在 DOM 完全加载后加载。为此,您需要为 [ng-cloak] 元素手动添加一些样式:

<head>
    ...
    <style>[ng-cloak] {display: none;}</style>
</head>

供您参考,由于 angular 可以在 DOM 之后或代码库之前加载,因此您不应在文档中包含 ng-app 属性,而是 bootstrap angular 手动避免任何异步问题:

require(['angular'], function(angular) {
    var app = angular.module('app', []);
    angular.bootstrap(document, ['app']);
});