敲除.js中的双向焦点绑定



我有这个自定义绑定,它使用应用于以下元素的焦点子元素的数据更新可观察量:

ko.bindingHandlers.selected =
  init: (element, valueAccessor) ->
    receiver = valueAccessor()
    $(element).focusin((event) ->
      data = ko.dataFor(event.target)
      receiver(data)
    )

这比标准hasFocus绑定效果更好,因为我希望页面的其他部分显示有关焦点项目的信息:

<ul data-bind="foreach: items, selected: selectedItem">
    <li><a href="#" data-bind="text: name"></a></li>
</ul>
<p data-bind="with: selectedItem">
    Selected: <span data-bind="text: name"></span>
</p>

现在我想将其设置为双向绑定,以便我可以更改脚本代码中的selectedItem,并使正确的列表元素以$.focus()为重点。任何想法如何扩展绑定以两种方式工作?

意识到我可能需要使用"控件后代绑定"方法,并且无法将绑定应用于与foreach绑定相同的元素,但这很好。我遇到的问题是,当调用更新函数时,子元素似乎没有绑定(dataFor返回未定义)。

您可以在 update 函数中遍历后代元素,并使用ko.dataFor检查要聚焦的元素:

update: (element, valueAccessor) ->
    receiver = valueAccessor()
    item = receiver()
    $(element).find("*").each((index, elem) ->      
      if (item == ko.dataFor(elem))
        $(elem).focus()
    )

演示 JSFiddle。

我不确定您决定创建自定义绑定以查找集合中的选定项并将其存储在可观察量中?

您可以简单地捕获事件并找出所选项目:

var data = [
    { "Id" : 0, "Name" : "Item0" },
    { "Id" : 1, "Name" : "Item1" },
    { "Id" : 2, "Name" : "Item2" },
    { "Id" : 3, "Name" : "Item3" },
    { "Id" : 4, "Name" : "Item4" },
    { "Id" : 5, "Name" : "Item5" },
    { "Id" : 6, "Name" : "Item6" },
    { "Id" : 7, "Name" : "Item7" }
]
function vm(){
    var self = this;
    self.items = ko.observableArray(data);
    self.selectedItem = ko.observable();
    self.selectItem = function(item){
        self.selectedItem(item);
    }
    self.select3rd = function(){
        self.selectedItem(self.items()[2]);
    }
}
ko.applyBindings(new vm());

目录:

<ul data-bind="foreach: items">
    <li><a href="#" data-bind="text: Name, event: { focus : $parent.selectItem }, attr: { 'tabindex' : $index }"></a></li>
</ul>
<p>Selected item: <span data-bind="text: ko.toJSON(selectedItem)"></span></p>
<button data-bind="click: select3rd">Select 3rd item</button>

小提琴就在这里

最新更新