• KnockoutJS 3.X API 第五章 高级应用(3) 虚拟元素绑定


    注意:这是一种高级技术,通常仅在创建可重用绑定的库时使用。 这不是你通常需要做的时候使用Knockout构建应用程序。

    Knockout的控制流绑定(例如,if和foreach)不仅可以应用于常规DOM元素,而且可以应用于由基于特殊注释的语法定义的“虚拟”DOM元素。 例如:

    <ul>
        <li class="heading">My heading</li>
        <!-- ko foreach: items -->
            <li data-bind="text: $data"></li>
        <!-- /ko -->
    </ul>

    自定义绑定也可以与虚拟元素一起使用,但要启用此功能,必须通过使用ko.virtualElements.allowedBindings API明确告知Knockout您的绑定理解虚拟元素。

    示例

    为了开始,这里是一个自定义绑定,随机化DOM节点的顺序:

    ko.bindingHandlers.randomOrder = {
        init: function(elem, valueAccessor) {
            // Pull out each of the child elements into an array
            var childElems = [];
            while(elem.firstChild)
                childElems.push(elem.removeChild(elem.firstChild));
     
            // Put them back in a random order
            while(childElems.length) {
                var randomIndex = Math.floor(Math.random() * childElems.length),
                    chosenChild = childElems.splice(randomIndex, 1);
                elem.appendChild(chosenChild[0]);
            }
        }
    };
    <div data-bind="randomOrder: true">
        <div>First</div>
        <div>Second</div>
        <div>Third</div>
    </div>

    但是,它不适用于虚拟元素。 如果您尝试以下操作:

    <!-- ko randomOrder: true -->
        <div>First</div>
        <div>Second</div>
        <div>Third</div>
    <!-- /ko -->

    ...那么你会得到错误绑定的“randomOrder”不能与虚拟元素一起使用。 让我们解决这个问题。 要使randomOrder可用于虚拟元素,请先通知Knockout允许它。 添加以下内容:

    ko.virtualElements.allowedBindings.randomOrder = true;

    现在不会有错误。 但是,它仍然无法正常工作,因为我们的randomOrder绑定是使用不理解虚拟元素的普通DOM API调用(firstChild,appendChild等)编码的。 这就是为什么KO要求你明确选择加入虚拟元素支持的原因:除非你的自定义绑定是使用虚拟元素API编码的,否则它不会正常工作!

    让我们更新randomOrder的代码,这次使用KO的虚拟元素API:

    ko.bindingHandlers.randomOrder = {
        init: function(elem, valueAccessor) {
            // Build an array of child elements
            var child = ko.virtualElements.firstChild(elem),
                childElems = [];
            while (child) {
                childElems.push(child);
                child = ko.virtualElements.nextSibling(child);
            }
     
            // Remove them all, then put them back in a random order
            ko.virtualElements.emptyNode(elem);
            while(childElems.length) {
                var randomIndex = Math.floor(Math.random() * childElems.length),
                    chosenChild = childElems.splice(randomIndex, 1);
                ko.virtualElements.prepend(elem, chosenChild[0]);
            }
        }
    };

    请注意,我们现在使用的是ko.virtualElements.firstChild(domOrVirtualElement),而不是使用像domElement.firstChild之类的API。 randomOrder绑定现在将正确地使用虚拟元素,例如<! - ko randomOrder:true - > ... <! - / ko - >。

    此外,randomOrder仍将使用常规DOM元素,因为所有ko.virtualElements API都与常规DOM元素向后兼容。

    Virtual Element APIs(虚拟元素API)

    Knockout提供了以下用于处理虚拟元素的功能。

    • ko.virtualElements.allowedBindings

      一个对象的键确定哪些绑定可与虚拟元素一起使用。 设置ko.virtual Elements.allowed Bindings.mySuper Binding = true以允许mySuperBinding与虚拟元素一起使用。

    • ko.virtualElements.emptyNode(containerElem)

      从真实或虚拟元素容器Elem中删除所有子节点(清除与其关联的任何数据,以避免内存泄漏)。

    • ko.virtualElements.firstChild(containerElem)

      返回实元素或虚拟元素容器元素的第一个子元素,如果没有子元素,则返回null。

    • ko.virtualElements.insertAfter(containerElem, nodeToInsert, insertAfter)

      插入节点插入作为实际或虚拟元素容器Elem的子元素,紧接在insertAfter之后的位置(其中insertAfter必须是containerElem的子元素)。

    • ko.virtualElements.nextSibling(node)

      返回在其真实或虚拟父元素中跟随节点的兄弟节点,如果没有下一个兄弟节点,则返回null。

    • ko.virtualElements.prepend(containerElem, nodeToPrepend)

      将nodePrepend插入为实元素或虚拟元素containerElem的第一个子元素。

    • ko.virtualElements.setDomNodeChildren(containerElem, arrayOfNodes)

      从真实或虚拟元素containerElem中删除所有子节点(在此过程中,清除与其关联的任何数据以避免内存泄漏),然后将所有节点fromarrayOfNodes作为其新子节点插入。

    请注意,这并不意味着完全替代了一整套常规DOM API。 Knockout仅提供一组最小的虚拟元素API,以便在执行控制流绑定时执行所需的各种转换。

  • 相关阅读:
    Ajax实现表格实时编辑
    自定义简单分页
    有趣的 0
    关于AJAX的一些事
    JQ中的FormData对象 ajax上传文件
    订单导出
    javaScript事件委托
    javascript递归函数
    详解javascript中this的工作原理
    详解JavaScript对象继承方式
  • 原文地址:https://www.cnblogs.com/smallprogram/p/5968678.html
Copyright © 2020-2023  润新知