• Knockoutjs实战开发:自定义标签支持虚拟元素(Creating custom bindings that support virtual elements)


    Knockoutjs的控制流程绑定(比如:if和foreach)不仅仅可以绑定在一个真实的DOM元素上,我们也可以将其绑定到一个虚拟的DOM元素上,这个DOM是由一个特殊语法定义的。比如:

    1 <ul> 
    2     <li class="heading">My heading</li> 
    3     <!-- ko foreach: items --> 
    4         <li data-bind="text: $data"></li> 
    5     <!-- /ko --> 
    6 </ul>

    我们自定义的标签也能向上例一样支持虚拟元素,但是,为了使用此功能,我们必须明确的告诉Knockoutjs我们自定义的绑定是支持虚拟元素的,此时我们可以使用ko.virtualElements.allowedBindings方法来通知Knockoutjs。

    例1、作为开始,我们首先自定义一个绑定,如下:

     1 <script type="text/javascript">
     2      ko.bindingHandlers.randomOrder = {
     3          init: function (elem, valueAccessor) {
     4              // Pull out each of the child elements into an array 
     5              var childElems = [];
     6              while (elem.firstChild)
     7                  childElems.push(elem.removeChild(elem.firstChild));
     8 
     9              // Put them back in a random order 
    10              while (childElems.length) {
    11                  var randomIndex = Math.floor(Math.random() * childElems.length),
    12                 chosenChild = childElems.splice(randomIndex, 1);
    13                  elem.appendChild(chosenChild[0]);
    14              }
    15          }
    16      };
    17 </script>

    此时我们自定义的绑定在真实的DOM元素中是可以起作用的,下面的元素会按照随机数重新进行排序:

    <div data-bind="randomOrder: true"> 
        <div>First</div> 
        <div>Second</div> 
        <div>Third</div> 
    </div>

    而我们自定义的绑定则不会在虚拟DOM元素中起作用。

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

    你可能还会获得以下的错误:The binding 'randomOrder' cannot be used with virtual elements。为了让我们自定义的绑定在虚拟DOM元素上起作用,我们可以使用下面的语句来通知Knockoutjs。

    ko.virtualElements.allowedBindings.randomOrder = true;

    此时,可能不会报错了,但是我们自定义绑定依然没有起作用,这是因为我们使用的编码方式并不能支持虚拟元素,这也就是为什么Knockoutjs会让我们选择性的支持虚拟元素:除非你编写的自定义绑定代码也支持虚拟元素,否则即使你加入上面的话,也不会起作用的。
    因此我们将上例中的自定义绑定做如下的修改:

     <script type="text/javascript">
         ko.bindingHandlers.randomOrder = {
             init: function (elem, valueAccessor) {
                 // Build an array of child elements 
                 alert("bb");
                 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.allowedBindings.randomOrder = true;
    </script>

    此时,我们的虚拟标签就可以使用了。此时我们使用ko.virtualElements.firstChild(domOrVirtualElement)代替了domElement.firstChild
    此例的完整代码如下:

     1 <script type="text/javascript" src="knockout-2.2.0.js"></script>
     2 
     3 
     4 -------------------------------------
     5 <!-- ko randomOrder: true --> 
     6     <div>First</div> 
     7     <div>Second</div> 
     8     <div>Third</div> 
     9 <!-- /ko -->
    10  <script type="text/javascript">
    11      ko.bindingHandlers.randomOrder = {
    12          init: function (elem, valueAccessor) {
    13              // Build an array of child elements 
    14              alert("bb");
    15              var child = ko.virtualElements.firstChild(elem),
    16             childElems = [];
    17              while (child) {
    18                  childElems.push(child);
    19                  child = ko.virtualElements.nextSibling(child);
    20              }
    21 
    22              // Remove them all, then put them back in a random order 
    23              ko.virtualElements.emptyNode(elem);
    24              while (childElems.length) {
    25                  var randomIndex = Math.floor(Math.random() * childElems.length),
    26                 chosenChild = childElems.splice(randomIndex, 1);
    27                  ko.virtualElements.prepend(elem, chosenChild[0]);
    28              }
    29          }
    30      };
    31      ko.virtualElements.allowedBindings.randomOrder = true;
    32 </script>
    33 
    34 <script type="text/javascript">
    35     var viewModel = {
    36         giftWrap: ko.observable(true)
    37     };
    38     ko.applyBindings(viewModel);
    39 </script>
    40 
    41 
    42 
    43   

     虚拟元素的API大家可以点击:http://knockoutjs.com/documentation/custom-bindings-for-virtual-elements.html查看,这里就不介绍了。

  • 相关阅读:
    (win10 64位系统中)Visual Studio 2015+OpenCV 3.3.0环境搭建,100%成功
    flutter环境搭建
    并发
    java集合继承关系图
    java中反射的使用
    android使用http3
    java之结合代码理解synchronized关键字
    阿里云ECS服务器将默认的Ubuntu系统改成桌面版
    python之demo2----改编自python官方提供的turtle_yinyang.py画阴阳的demo
    python之demo1----改编自turtle.py文件中的demo
  • 原文地址:https://www.cnblogs.com/wukong65/p/2815986.html
Copyright © 2020-2023  润新知