最近項(xiàng)目中有一個(gè)頁(yè)面一直報(bào)錯(cuò)逗扒,但是又可以正常使用,和其他頁(yè)面對(duì)比后發(fā)現(xiàn)將ng-show改為ng-if之后報(bào)錯(cuò)提示就消失了掰盘,覺(jué)得很有必要找到問(wèn)題根本原因
實(shí)現(xiàn)原理
ng-show/ng-hide是根據(jù)表達(dá)式通過(guò)css樣式方式來(lái)控制元素的顯示與隱藏摄悯,類似display:"none"的效果,對(duì)應(yīng)的DOM元素會(huì)一直存在于當(dāng)前頁(yè)面中庆杜。而ng-if是根據(jù)表達(dá)式的值動(dòng)態(tài)的在當(dāng)前的頁(yè)面中添加/刪除頁(yè)面元素,如果賦值表達(dá)式的值為false碟摆,那么這個(gè)元素就會(huì)從頁(yè)面中刪除晃财,否則會(huì)添加一個(gè)元素。
主要區(qū)別
ng-if重新創(chuàng)建元素時(shí)用的是它們編譯后的狀態(tài),如果ng-if內(nèi)部的代碼加載之后被jQuery修改過(guò)(例如用addClass)断盛,那么當(dāng)ng-if的表達(dá)式值為false時(shí)罗洗,這個(gè)DOM元素會(huì)被移除,表達(dá)式再次成為true時(shí)這個(gè)元素及其內(nèi)部的子元素會(huì)被重新插入DOM钢猛,此時(shí)這些元素的狀態(tài)會(huì)是它們的原始狀態(tài)伙菜,而不是它們上次被移除時(shí)的狀態(tài)。而ng-show和ng-hide則可以保留DOM元素上次修改后的狀態(tài)
作用域方面兩者也存在差異命迈,當(dāng)一個(gè)元素被ng-if從DOM中刪除時(shí)贩绕,與其關(guān)聯(lián)的作用域也會(huì)被銷毀。而且當(dāng)它重新加入DOM中時(shí)壶愤,則會(huì)生成一個(gè)新的作用域缅叠,而ng-show和ng-hide則不會(huì)
實(shí)際案例
通過(guò)編寫(xiě)代碼在瀏覽器中我們可以很明顯的看到兩者的區(qū)別
#頁(yè)面html代碼片段
<div ng-controller="MainCtrl" class="ng-scope">
<div ng-show="false" class="ng-hide">
ng-show = false
</div>
<div ng-show="true" class="">
ng-show=true
</div>
<!-- ngIf: true -->
<div ng-if="true" class="ng-scope">
ng-if = true
</div>
<!-- end ngIf: true -->
<!-- ngIf: false -->
</div>
還有一個(gè)我覺(jué)得非常好的案例戳這里渡紫,可是說(shuō)是很直觀了,這里就不直接搬運(yùn)了
項(xiàng)目問(wèn)題
看完兩者的區(qū)別之后,回到自己的項(xiàng)目中毁渗,發(fā)現(xiàn)報(bào)錯(cuò)的原因是因?yàn)槲沂褂昧薾g-show來(lái)控制內(nèi)容的顯示與隱藏,所以無(wú)論表達(dá)式的值是true或者false迈套,頁(yè)面都會(huì)先將DOM元素加載出來(lái)甲脏。但是DOM元素能否加載其實(shí)依賴某個(gè)值是否存在,而這個(gè)值是需要去后臺(tái)進(jìn)行查詢的蒙秒,所以頁(yè)面一開(kāi)始無(wú)法獲取到這個(gè)值勃黍,js中就報(bào)錯(cuò)了。最后將ng-show替換成ng-if税肪,等值查詢出來(lái)再去顯示DOM元素就不會(huì)有問(wèn)題啦~
參考1:(十四)ng-if與ng-show溉躲、ng-hide指令的區(qū)別和注意事項(xiàng)
參考2:Angular.js中ng-if、ng-show和ng-hide的區(qū)別介紹