等同于 optionsAfterRender 在敲除中的 foreach 绑定

Equivalent for optionsAfterRender on a foreach binding in knockout

在 Knockout 中,“options”绑定有一个可选参数 `optionsAfterRender,用于在插入时修改各个选项标签。你可以find more details in the documentation

对于我的 select 列表之一,我不得不使用 foreach 绑定,因为它需要使用 optgroup.

的两级绑定
<select  data-bind="foreach: { data: availableData,
                              value: editDataId">
  <optgroup data-bind="attr: {label: groupTitle}, foreach: groups">
    <option data-bind="value: id, attr: {title: name }"></option>
  </optgroup>
</select>

不过我也想在绑定后修改这些选项

foreach 有一个 afterRender 选项,但它的行为似乎与 optionsAfterRender 非常不同。我能够让它针对 select 列表中的所有选项执行,如下所示:

<select  data-bind="foreach: { data: availableData,
                              value: editDataId,
                              afterRender: doStuff">
  <optgroup data-bind="attr: {label: groupTitle}, foreach: groups">
    <option data-bind="value: id, attr: {title: name }"></option>
  </optgroup>
</select>

然后在视图模型中

doStuff(elements, data): void {
    for (let entry of elements[1].querySelectorAll("option")) {
        ko.applyBindingsToNode(entry, {disable: true }, entry);
    }
}

(我真的不想将它们全部禁用 - 这只是一个简单的测试) - 但这导致整个 select 列表根本不呈现的奇怪结果。检查时,节点仍然存在 - 在 HTML 中并且可以遍历和记录它们 - 但它们没有出现在页面上。

这不是因为他们被禁用了。绑定中的某些东西导致整个事情变得古怪。有没有办法可以在这个 foreach 绑定上模仿 optionsAfterRender 的操作?

除了修复未关闭的 foreach 绑定拼写错误外,我还发现我需要将选项的 "title" 绑定更改为 "label" 才能显示单个选项文本。除此之外,您的代码似乎按预期运行。

function viewModel(){
  var self = this;
  self.editDataId = 1;
  self.availableData = [
    { groupTitle: 'group1', groups: [ {id: 1, name: 'item1'}, {id: 2, name: 'item2'} ] } ,
    { groupTitle: 'group2', groups: [ {id: 3, name: 'item3'}, {id: 4, name: 'item4'} ] } 
  ];
 
  self.doStuff = function(elements, data) {
    for (let entry of elements[1].querySelectorAll("option")) {
      ko.applyBindingsToNode(entry, { disable: true }, entry);
    }
  }
}

ko.applyBindings(new viewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

<select  data-bind="foreach: { data: availableData,
                              value: editDataId,
                              afterRender: doStuff }">
  <optgroup data-bind="attr: {label: groupTitle}, foreach: groups">
    <option data-bind="value: id, attr: {label: name}"></option>
  </optgroup>
</select>