Reputation:
Basically, my problem is that "I am {{ 10 + 13 }}" is what is being rendered for a second/half a second, before the "store" module is being created in 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 sets the requirejs configs, requires the angular library and sets the "store" module:
require.config({
paths: {angular: '../bower_components/angular/angular.min'},
shim: {angular: {exports: 'angular'}}
});
require(['angular'], function(angular) {
var app = angular.module('store', []);
});
I think the reason this occurs, is because main.js and the angular library are being loaded asynchronously by requirejs (with an "async" attribute on the script tag), so the DOM gets rendered before the store module has been created, thus creating a delay.
What would I have to do to avoid this gap that occurs between rendering "I am {{ 10 + 13 }}" and "I am 13"? I could load both main.js and the angular js synchronous/without requirejs, but that does not seem like a best practice.
Upvotes: 2
Views: 1520
Reputation: 21901
I think you can use ng-cloack
directive
<body>
I am <span ng-cloak>{{ 10 + 13 }}</span>
</body>
add css
[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
display: none !important;
}
didn't test you can give a try. :)
UPDATE
hide the <body>
until angular
available.
.initial-hide {
display: none;
}
.show {
display: block !important;
}
<body class="initial-hide" ng-class="{show : initedScripts}">
......
......
</body>
body will get initial-hide
and gets hide until show
class applied to it. show
class applied when variable initedScripts
sets to true
.
in the 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.
here is a DEMO
i added a 2 seconds timeout to delay the invoking of angularjs by requirJs
Upvotes: 2
Reputation:
As @K.Toress mentioned, the way to fix this problem would be to use ng-cloak
on the body element or more specifically on the problematic elements to improve the rendering of the page.
Some css/style is needed to put the ng-cloak elements in display: none;
, so if you are using angular in CSP mode, you will have no problem, because the angular-csp.css stylesheet would normally be included. However, if you are not using angular in CSP mode, the css rule embedded within angular.js/angular.min.js would not have any effect, since the library will most likely be loaded after the DOM is completely loaded. For this reason, you need to manually add some style for the [ng-cloak]
elements:
<head>
...
<style>[ng-cloak] {display: none;}</style>
</head>
For your information, since angular can be loaded after the DOM or before the code base, you should not include an ng-app
attribute to the document, but rather bootstrap angular manually to avoid any asynchronous issues:
require(['angular'], function(angular) {
var app = angular.module('app', []);
angular.bootstrap(document, ['app']);
});
Upvotes: 0
Reputation: 6143
You can wrap your expressions to be interpolated in some custom tags that are supported by angular. Thus they won't be rendered by browser before angular is loaded and compiles all stuff on your page.
Which one to choose depends on your real markup. You can even wrap this in a custom directive
Upvotes: 0