【问题标题】:Knockout pass $parent for click event bindingKnockout pass $parent 用于点击事件绑定
【发布时间】:2013-10-24 17:55:03
【问题描述】:

我有这个代码:

<div id="menu">
  <ul data-bind="foreach: elements">
    <li>
      <span data-bind="text:domObj().tagName +' [' + classOriginal() + ']', click: $root.elementClick"></span>
      <ul class="menuclassitem" style="display:none" data-bind="foreach: classFixes">
        <li data-bind="text:$data, click:$root.classClick.bind($parent)"></li>
      </ul>
    </li>
  </ul>
</div>

如您所见,我试图将 $parent 对象(“元素”数组中的当前项)传递给 $root.classClick 函数,但实际传递的值是当前内部的 $data循环(当前“classFixes”数组的$data)

有人知道如何在 classClick 函数中使用 $parent 吗?

【问题讨论】:

标签: javascript knockout.js


【解决方案1】:

classClick 函数中的“this”变量是 $parent。传递给 classClick 的第一个参数是 $data。 This fiddle demonstrates

ko.applyBindings({
elements: [
    {
        classFixes : ["ab","cd"]
    },
    {
        classFixes : ["ef","gh"]
    }
 ],
 classClick : function(first)
 {
    alert(JSON.stringify(this));
    alert(JSON.stringify(first));
 }
});

【讨论】:

    【解决方案2】:

    这是一个很老套的问题,但它仍然可能对某人有所帮助。

    这个问题更多地与.bind() 的方式有关,而不是与 KnockoutJS。所以首先我们需要了解 bind() 是如何工作的:

    bind() 方法创建一个新函数,在调用该函数时,该函数具有 此关键字设置为提供的值,具有给定的序列 调用新函数时提供的任何参数之前的参数。 more...

    现在让我们回到问题上来。默认情况下,KnockoutJS 将当前的$data 作为click-binding 接收的函数的第一个参数传递。相同的$data 用作默认上下文。在@DorR 编写click:$root.classClick.bind($parent) 之后,单击绑定收到了一个具有重新定义上下文(到$parent)和预定义参数的函数,这允许KO 将$data 作为第一个参数传递。 $parent 现在可以在classClick 中作为this 访问。

    为了说明它是如何工作的,我在下面制作了这个小 sn-p。尝试单击不同列中的按钮并检查下面的调试日志,以查看 KO 传递的参数如何被.bind() 预定义的参数向右移动

    function VM() {
      const self = this;
      self.debug = ko.observable('');
      self.catalog = [
        {
          name:'Section1',
          items:[
            {id:1,name:'Item1'},
            {id:2,name:'Item2'},
          ]
        },
        {
          name:'Section2',
          items:[
            {id:4,name:'Item4'},
          ]
        }
      ];
      
      self.orderClick = function(arg1,arg2,arg3,arg4) {
        let dbgText = "this:<br>&nbsp;&nbsp;&nbsp;";
        dbgText += JSON.stringify(this);
        dbgText += "<br>1st arg:<br>&nbsp;&nbsp;&nbsp;";
        dbgText += JSON.stringify(arg1);
        dbgText += "<br>2nd arg:<br>&nbsp;&nbsp;&nbsp;";
        dbgText += JSON.stringify(arg2);
        dbgText += "<br>3nd arg:<br>&nbsp;&nbsp;&nbsp;";
        dbgText += JSON.stringify(arg3);
        dbgText += "<br>4th arg:<br>&nbsp;&nbsp;&nbsp;";
        dbgText += JSON.stringify(arg4);
        self.debug(dbgText);
      }
    }
    
    ko.applyBindings(new VM())
    table {
      border-collapse: collapse;width:100%;
    }
    
    td {
      border:1px solid #CCC;
      text-align:center;
      font-family:sans-serif;
      font-size:11px;
      white-space:nowrap;
    }
    
    button {
      display:block; margin:5px auto; 
    }
    
    .dbglog {
      padding:5px 10px;
      border:1px solid #AAA;
      background-color:#EEE;
      font-family:"Lucida Console", Monaco, monospace;
      font-size:12px;min-height:50px;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
    <table data-bind="foreach: catalog">
        <tr>
            <td colspan=10><b data-bind="text:$data.name"></b></td>
            <td>
              <table data-bind="foreach:$data.items" class=nested>
              <tr>
                <td width=10%> 
                  <i data-bind="text:$data.name"></i>
                </td>
                <td width=30%> 
                  no .bind()
                  <button data-bind="click:$root.orderClick">click</button> 
                </td>
                <td width=30%> 
                  .bind($parent) 
                  <button data-bind="click:$root.orderClick.bind($parent)">click</button> 
                </td>
                <td width=30%> 
                  .bind($parent,$data,'smthelse') 
                  <button data-bind="click:$root.orderClick.bind($parent,$data,'text')">click</button> 
                </td>
              </tr>
            </table>
            </td>
        </tr>
    </table>
    <div class=dbglog data-bind="html:$root.debug"></div>

    希望这个答案对某人有所帮助。 =)

    【讨论】:

      猜你喜欢
      • 2013-07-31
      • 1970-01-01
      • 1970-01-01
      • 2013-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-18
      • 2015-01-29
      相关资源
      最近更新 更多