TwoWay焦点绑定在knockout.js

时间:2014-01-17 08:03:41

标签: javascript jquery knockout.js

我有这个自定义绑定,用于应用元素的聚焦子元素的数据更新observable:

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返回undefined)。

2 个答案:

答案 0 :(得分:1)

您可以浏览update函数中的后代元素,并使用ko.dataFor检查要关注的元素:

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

演示JSFiddle

答案 1 :(得分:0)

我不确定你决定创建一个自定义绑定来查找集合中的选定项目并将其存储在一个可观察的项目中?

您只需捕获一个事件并找到所选项目:

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());

HTML:

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

And the fiddle is here