We know that browsers and angular render pages consume a certain amount of time when the application page or component needs to load data. The spacing here may be small or even a little different, but it can be very long, which can cause our users to see pages that have not been rendered.
This situation is called Flash of unrendered Content (Fouc) (K)? and is always unwanted. Below we will introduce several different ways to prevent this from happening to our users.
1, Ng-cloak
The ng-cloak instruction is a angular built-in instruction that hides all elements it contains:
Ng-cloak implementation principle for a directive, page initialization is in the DOM Heade add a line of CSS code, as follows:
<pre class= "Prettyprint linenums" >
[Ng\:cloak],[ng-cloak], [Data-ng-cloak], [X-ng-cloak],. Ng-cloak,. x-ng-cloak{
Display:none! important
}
</pre>
<pre class= "Prettyprint linenums" >
[Ng\:cloak],[ng-cloak], [Data-ng-cloak], [ X-ng-cloak],. Ng-cloak,. x-ng-cloak{
display:none! important;
}
</pre>
Angular sets the element with Ng-cloak to Display:none.
When the angular resolves to a ng-cloak node, the elements Ng-cloak and CALSS are removed at the same time, thus preventing the node from blinking. As follows:
<script type = "text/ng-template" id = "scenario.js-150" >
It (' should remove the template directive and CSS class ' , function () {
Expect (Element ('. Doc-example-live #template1 '). attr (' Ng-cloak ')) not
(). tobedefined ();
Expect (Element ('. Doc-example-live #template2 '). attr (' Ng-cloak '
). Not (). tobedefined ();
});
</script>
<script type = "text/ng-template" id = "scenario.js-150" >
It (' should remove the template Directive and CSS class ', function () {
Expect ('. Doc-example-live #template1 '). attr (' Ng-cloak '))
Not (). tobedefined ();
Expect (Element ('. Doc-example-live #template2 '). attr (' Ng-cloak '
). Not (). tobedefined ();
});
</script>
2, Ng-bind
Ng-bind is another built-in instruction in angular to manipulate bound page data. We can use Ng-bind instead of {{}} to bind elements to the page;
Using Ng-bind instead of {{}} can prevent the rendering of the not-yet-rendered {{}} to the user, and replacing {{}} with an empty element rendered with Ng-bind will be a lot friendlier.
The example above can be rewritten as follows so that the page can be prevented from appearing {}}
3, Resolve
when using routes (routing) between different pages, we have another way of preventing the page from being rendered before the data is completely loaded into the route.
Using resolve in route (routing) allows us to get the data we need to load before route (routing) is fully loaded. When the data is loaded successfully, the route changes and the page is presented to the user; The data is not loaded successfully route will not change, the $routeChangeError event will get fired. "$ Routechangeerror event (not) will be activated? 】
Angular.module (' myApp ', [' Ngroute '])
. config (function ($routeProvider) {
$routeProvider
. When ('/ Account ', {
controller: ' Accountctrl ',
templateurl: ' views/account.html ',
resolve: {
//We Specify a Promise to is resolved
account:function ($q) {
var d = $q. Defer ();
$timeout (function () {
d.resolve ({
id:1,
name: ' Ari Lerner '
})
}, 1000);
Return d.promise}})
};
The resolve item requires a Key/value object, the key is a resolve-dependent name, and value can be a string (as a service) or a return-dependent method.
Resolve is very useful then resolve value returns a promise that becomes resolved or rejected.
When routing loads, the keys in the Resolve parameter can be used as an injection dependency:
Angular.module (' myApp ')
. Controller (' Accountctrl ',
function ($scope, account) {
$scope. Account = account;
});
We can also use the Resolve key to pass the results returned by the $http method, as $http returns promises from it's methods calls:
Angular.module (' myApp ', [' Ngroute '])
. config (function ($routeProvider) {
$routeProvider
. When ('/ Account ', {
controller: ' Accountctrl ',
templateurl: ' views/account.html ',
resolve: {account
: function ($http) {return
$http. Get (' Http://example.com/account.json ')}})
});
It is recommended to define a separate service to use the Resolve key, and to use the service to return the required data accordingly (this is easier to test). To do this, we need to create a service:
First, take a look at Accountservice,
Angular.module (' app ')
. Factory (' Accountservice ', function ($http, $q) {return
{
getaccount:function () {
var d = $q. Defer ();
$http. Get ('/account ')
. Then (function (response) {
d.resolve (response.data)
}, Function err (reason) {
d.reject (reason);
});
Return d.promise}
}
)
After defining the service, we can use this service to replace the direct call to $http in the above code:
Angular.module (' myApp ', [' Ngroute '])
. config (function ($routeProvider) {
$routeProvider
. When ('/ Account ', {
controller: ' Accountctrl ',
templateurl: ' views/account.html ',
resolve: {
//We Specify a Promise to is resolved
account:function (accountservice) {return
accountservice.getaccount ()
}
}
})
});