【问题标题】:Directive rendering delay when using angularjs and requirejs使用 angularjs 和 requirejs 时的指令渲染延迟
【发布时间】:2015-06-25 00:17:03
【问题描述】:

基本上,我的问题是“我是 {{ 10 + 13 }}”是在 main.js 中创建“存储”模块之前呈现一秒/半秒的内容。

<!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 异步加载的(在 script 标签上有一个“async”属性),所以 DOM 在 store 模块创建之前就被渲染了,从而造成延迟。

我应该怎么做才能避免在呈现“我是 {{ 10 + 13 }}”和“我是 13”之间出现这种差距?我可以同时加载 main.js 和 angular js 同步/不使用 requirejs,但这似乎不是最佳实践。

【问题讨论】:

    标签: angularjs requirejs


    【解决方案1】:

    我认为你可以使用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

    更新

    隐藏&lt;body&gt; 直到angular 可用。

    .initial-hide {
       display: none;
    }
    
    .show {
        display: block !important;
    }
    
    
    <body class="initial-hide" ng-class="{show : initedScripts}">
        ......
        ......
    </body>
    

    body 将获得initial-hide 并隐藏,直到应用show 类。当变量initedScripts 设置为true 时应用show 类。

    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-csp.css 样式表。我不认为我希望这样做,因为我不在 CSP 模式下。即使在非 CSP 模式下,ng-cloack 指令是否也可以工作?
    • 上面说在非CSP模式下,css规则是嵌入到angular.js和angular.min.js中的……所以我不明白为什么它不起作用。跨度>
    • 啊,但是库是在加载DOM之后才加载的,所以我遇到的问题和以前完全一样。
    • 我更新了答案可能会解决您的问题。 :) 请检查。
    • 嘿感谢您的帮助!如果您在下面查看我的答案,我想我找到了更好的解决方案。 Angular 在编译模板时会自动删除ng-cloak 属性,因此不需要额外的类。竖起大拇指!
    【解决方案2】:

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

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

    【讨论】:

    • 我想我仍然会遇到同样的问题,因为它不会阻止 Angular html 模板在应用程序加载时被浏览器以其原始(未编译)形式短暂显示
    【解决方案3】:

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

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

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

    请注意,由于 Angular 可以在 DOM 之后或代码库之前加载,因此您不应在文档中包含 ng-app 属性,而应手动引导 Angular 以避免任何异步问题:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多