ms-if是屬於流程綁定的一種,若是表達式爲真值那麼就將當前元素輸出頁面,不是就將它移出DOM樹。它的效果與上一章節的ms-visible效果看起來類似的,但它會影響到:empty僞類,並能更節約性能。ms-if還有一個分支,叫ms-if-loop,它是配合ms-repeat綁定使用,所以之後再說。javascript
咱們能夠經過如下例子比較一下二者:html
<!DOCTYPE HTML> <html> <head> <title>ms-if</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <script src="avalon.js" ></script> <script> var vmodel = avalon.define({ $id: "test", object: {} }) setTimeout(function() { vmodel.object = {id: "132", message: "顯示!!"} }, 3000) setTimeout(function() { vmodel.object = {} }, 5000) </script> </head> <body> <div ms-controller="test" > 這是比較輸出結果:{{object.id != null}} <div ms-visible="object.id != null"> 這是visible的: <span>{{object.message}}</span> </div> <div ms-if="object.id != null"> 這是if的: <span>{{object.message}}</span> </div> </div> </body> </html>
ms-if的實現比ms-visible複雜多了,若是一開始掃描到此元素,計算其值爲false,它就不會再掃描裏面的元素,而且當即移除此元素。這正是它比ms-visible性能更優的關鍵。爲了能在從新插入DOM時找到正確的位置,avalon還得建立一個註釋節點作路標。而被移除的元素是放在一個叫ifSanctuary的DIV中,方便統一管理。java
"if": function(data, vmodels) {//這裏是第一次掃描時的執行函數 var elem = data.element elem.removeAttribute(data.name) if (!data.placehoder) { data.msInDocument = data.placehoder = DOC.createComment("ms-if") } data.vmodels = vmodels parseExprProxy(data.value, vmodels, data) }, "if": function(val, elem, data) {//這是每次改變ViewModel對應屬性時的執行函數 var placehoder = data.placehoder if (val) { //插回DOM樹 if (!data.msInDocument) { data.msInDocument = true if(placehoder.parentNode) placehoder.parentNode.replaceChild(elem, placehoder) } } if (rbind.test(elem.outerHTML.replace(rlt, "<").replace(rgt, ">"))) { scanAttr(elem, data.vmodels) } } else { //移出DOM樹,放進ifSanctuary DIV中,並用註釋節點佔據原位置 if (data.msInDocument) { data.msInDocument = false if(elem.parentNode) elem.parentNode.replaceChild(placehoder, elem) } placehoder.elem = elem ifSanctuary.appendChild(elem) } } },
最後,咱們仍是用切換卡例子結束本章吧。app
<!DOCTYPE html> <html> <head> <title>TODO supply a title</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width"> <script src="avalon.js"></script> <script > var model = avalon.define({ $id: "test", currentIndex: 0, toggle: function(index) { model.currentIndex = index } }) </script> <style> button{ width:150px; height:30px; line-height: 30px; text-align: center; } .ms-tabs{ border:1px solid violet; width: 430px; padding:5px; height: 200px; } </style> </head> <body ms-controller="test" > <button ms-click="toggle(0)">觸發器1</button> <button ms-click="toggle(1)">觸發器2</button> <button ms-click="toggle(2)" >觸發器3</button> <div class="ms-tabs" ms-if="currentIndex === 0">切換卡1<br/>其餘內容</div> <div class="ms-tabs" ms-if="currentIndex === 1">切換卡2<br/>及司徒正美</div> <div class="ms-tabs" ms-if="currentIndex === 2">切換卡3<br/>最後一個了</div> </body> </html>