Knockoutjs中的BindingHandler。 建立自己的ListView

我想用selectedItem和Itemsource构建我自己的listView。

我已经开始了一个jsFiddle http://jsfiddle.net/andersb79/53xRL/1/

能否帮助我正确指导我如何建立这个目标。 我没有看到这样做的具有约束力的汉德尔。

我想要的是这样的。

data-bind="myListView : { items : comments, selectedItem : selectedComment}" 

在您的自定义绑定中,您需要:

  1. 为列表中的每个项创建一个元素
  2. 将该元素附加到父元素
  3. 为每个在原始视图模型上设置selectedItem的元素添加单击处理程序

为清晰起见,我还突出显示了当前所选项目。

 ko.bindingHandlers.myListView = { update: function(element, valueAccessor) { var value = ko.utils.unwrapObservable(valueAccessor()), //get the list of items items = value.items(), //get a reference to the selected item observable selectedItem = value.selectedItem, //get a jQuery reference to the element $element = $(element), //get the currently selected item currentSelected = selectedItem(); //clear the parent of any existing children $element.html(""); for (var index = 0; index < items.length; index++) { (function() { //get the list of items var item = ko.utils.unwrapObservable(items[index]), //create a child element with a click handler $childElement = $("
  • ") .text(item.id() + " " + item.text()) .click(function() { //remove selected class on all siblings $(this).siblings().removeClass("selected"); //add selected class on this item $(this).addClass("selected"); //set the observable 'selected item' property on the source view model selectedItem(item); }); //add the selected class if this item is the current selected item if (item == currentSelected) { $childElement.addClass("selected"); } //add the child to the parent $element.append($childElement); })(); } } };
  • 这是一个有效的例子

    注意:当我使用update而不是init方法时,它将在更新注释列表时起作用

    更新

    如果要将原始DIV的内容用作每个已创建项目的模板,则需要执行以下两个步骤:

    1. 初始化时抓取元素的原始内容,并使用它代替上面的硬编码内容
    2. 在将创建的元素添加到DOM之前,将绑定应用于创建的元素

        ko.bindingHandlers.myListView = { init: function(element) { var $element = $(element), originalContent = $element.html(); $element.data("original-content", originalContent); return { controlsDescendantBindings: true } }, update: function(element, valueAccessor) { var value = ko.utils.unwrapObservable(valueAccessor()), //get the list of items items = value.items(), //get a reference to the selected item observable selectedItem = value.selectedItem, //get a jQuery reference to the element $element = $(element), //get the currently selected item currentSelected = selectedItem(), //get the current content of the element elementContent = $element.data("original-content"); $element.html(""); for (var index = 0; index < items.length; index++) { (function() { //get the list of items var item = ko.utils.unwrapObservable(items[index]), //create a child element with a click handler $childElement = $(elementContent) .click(function() { //remove selected class on all siblings $(this).siblings().removeClass("selected"); //add selected class on this item $(this).addClass("selected"); //set the observable 'selected item' property on the source view model selectedItem(item); }); ko.applyBindings(item, $childElement[0]); //add the selected class if this item is the current selected item if (item == currentSelected) { $childElement.addClass("selected"); } //add the child to the parent $element.append($childElement); })(); } } 

      };

    请注意,我们必须通过从init方法返回{ controlsDescendantBindings: true }来防止被敲除处理的div的内容。

    这是一个更新的例子