BindingHandler在Knockoutjs。 打造自己的ListView(Binding

2019-09-18 03:21发布

我想建立自己的ListView与selectedItem属性和的ItemSource。

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

能否请你帮我约我应该怎么建立这个正确的方向。 我没有带看到bindingHanlder是做到这一点。

我想是这样的。

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

Answer 1:

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

  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 = $("<li>")
                    .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); })(); } } 

    };

需要注意的是,我们必须防止通过返回淘汰赛正在处理的div的内容{ controlsDescendantBindings: true }从我们init方法。

下面是一个更新的例子



文章来源: BindingHandler in Knockoutjs. build own ListView