在使用Anguarjs进行web开发或者进行SPA(single page application)开发时,每每会遇到下面这样的问题。css
刷新页面时,页面会出现一些乱码,这里的乱码具体是指`{{expression}}`或者`{{expression | filter}}`这种形式的表达式乱码,而后这些乱码又快速的消失了,而后页面就正常了。这个问题的缘由是,在一些现代浏览器,好比Chrome,Firefox等中尤其严重。固然还跟环境的网络速度有关。html
出现这个问题的根本缘由是,JavaScript操做DOM都是在DOM加载完成(DOM Ready)以后的才进行的。换句话说,Angularjs只会在DOM Ready以后才回去解析html模版以及Angularjs的directive,在这以前html模版中的内容会被原封不动的展现在页面,这时候就会出现所谓的乱码问题。web
那么咱们如何解决这个问题呢?express
Angularjs官方针对这个问题提供了原生的解决方案,就是咱们今天要说的主角 ng-cloak
指令。浏览器
咱们先来看一下Angularjs的源码中对这个 ng-cloak
是如何实现的。网络
Angularjs将 ng-cloak
实现为directive,其代码以下,app
!angular.$$csp() && angular .element(document) .find('head') .prepend('<style type="text/css">' + '@charset "UTF-8";' + '[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide{display:none !important;}' + 'ng\\:form{display:block;}' + '.ng-animate-block-transitions{transition:0s all!important;-webkit-transition:0s all!important;}' + </style>');
你们不要对这一坨代码感到畏惧,其实它作的事很简单,就是在html的中 head
标签中插入一段内联的css样式。其中部分的代码是这样的,ide
[ng\\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak, .ng-hide { display:none !important; }
很显然,Angularjs对 ng-cloak
相关的元素设置了 display: none !important
这样一个属性,目的就是隐藏相关元素。这样在在DOM尚未Ready的时候,将相关元素隐藏起来,这样页面就不会出现乱码了。spa
当DOM Ready的时候,Angularjs开始解析指令。咱们来看一下 ng-cloak
这个指令都作了哪些事情,code
var ngCloakDirective = ngDirective({ compile: function(element, attr) { attr.$set('ngCloak', undefined); element.removeClass('ng-cloak'); } });
可见,当Angularjs开始解析 ng-cloak
指令的时候,又会把这个样式给去除掉。这样页面又显示了。
经过以上分析,咱们知道了使用 ng-cloak
指令来避免页面出现乱码的原理,其实经过先隐藏后显示来规避了DOM还没有Ready这段时间的真空期。
在实际使用的过程当中,咱们要想使上面的过程完美表现,就必需要先在 head
标签中先引入Angularjs的源码,而不能在页面的最后引入Angularjs文件。
由于后者会形成这样一种状况:在Angularjs文件还没引入时,意味着还没给 ng-cloak
相关元素作隐藏处理,页面就已经展现了,这是页面仍然会出现乱码。
可是通常性的原则告诉咱们, 应该把css文件放在头部,把js文件放在尾部 。那么咱们如何解决这个矛盾呢?
解决方案是,咱们手动在 head
中将 ng-cloak
相关的元素设置为隐藏,即添加以下的代码,
<head> <style> [ng:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak { display:none !important; } </style> </head>
或者将这一段代码放在咱们在 head
中加载的css文件中,这样就能够确保页面加载的时候,无论它有没有DOM Ready, ng-cloak
相关元素确定是隐藏的。
若是你发如今 body
上加了 ng-cloak
,可是仍然不起做用,那么缘由应该就是上面所描述的,这时候你就须要在 head
中添加隐藏代码或者在引入的css文件中添加相关代码了。
最后提一点,若是 中的表达式仅仅是展现一些文本内容,咱们能够使用
ng-bind
这个指令来实现。