6

我有这个代码:

<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 ?

4

2 回答 2

1

相当化石的问题,但它仍然可以帮助某人。

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

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

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

为了说明它是如何工作的,我在下面制作了这个小片段。尝试单击不同列中的按钮并检查下面的调试日志,以查看 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>

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

于 2019-09-29T13:00:09.697 回答
0

classClick 函数中的“this”变量是 $parent。传递给 classClick 的第一个参数是 $data。这个小提琴演示

ko.applyBindings({
elements: [
    {
        classFixes : ["ab","cd"]
    },
    {
        classFixes : ["ef","gh"]
    }
 ],
 classClick : function(first)
 {
    alert(JSON.stringify(this));
    alert(JSON.stringify(first));
 }
});
于 2013-10-16T22:07:36.757 回答