ms-if是属于流程绑定的一种,如果表达式为真值那么就将当前元素输出页面,不是就将它移出DOM树。它的效果与上一章节的ms-visible效果看起来相似的,但它会影响到:empty伪类,并能更节约性能。ms-if还有一个分支,叫ms-if-loop,它是配合ms-repeat绑定使用,因此以后再说。
我们可以通过以下例子比较一下两者:
ms-if 这是比较输出结果:{ {object.id != null}}这是visible的: { {object.message}}这是if的: { {object.message}}
ms-if的实现比ms-visible复杂多了,如果一开始扫描到此元素,计算其值为false,它就不会再扫描里面的元素,并且立即移除此元素。这正是它比ms-visible性能更优的关键。为了能在重新插入DOM时找到正确的位置,avalon还得创建一个注释节点做路标。而被移除的元素是放在一个叫ifSanctuary的DIV中,方便统一管理。
"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) } }},
最后,我们还是用切换卡例子结束本章吧。
TODO supply a title 切换卡1 其他内容切换卡2 及司徒正美切换卡3 最后一个了