Jquery Knockoutjs中的BindingHandler。构建自己的ListView

Jquery Knockoutjs中的BindingHandler。构建自己的ListView,jquery,knockout.js,Jquery,Knockout.js,我想用selectedItem和Itemsource构建自己的listView 我开了一家JSFIDLE 你能帮助我在正确的方向上,我应该如何建立这个。 我还没见过这么做的人 我想要的是这样的东西 data-bind="myListView : { items : comments, selectedItem : selectedComment}" 在自定义绑定中,您需要: 为列表中的每个项目创建一个元素 将该元素附加到父元素 向在原始视图模型上设置selectedItem的每个元素添加一个单

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

我开了一家JSFIDLE

你能帮助我在正确的方向上,我应该如何建立这个。 我还没见过这么做的人

我想要的是这样的东西

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

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

  • 为列表中的每个项目创建一个元素
  • 将该元素附加到父元素
  • 向在原始视图模型上设置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);
                })();
            }
    
        }
    };
    
    })

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


    这是一个Whoo,非常感谢。但是,如果我想成为abel,在div(注释或模板)中包含代码,该怎么办呢。在页面上,我想在这里的代码,这是一个评论。所以我可以在这里做data bind=“text:comment”非常有帮助。你不能在bindinghandler中连接并使用foreach绑定来利用模板绑定吗?如果我想这样做的话。myListView:{Items:Comment,template:'myTemplate',selectedItem:selectedItem}没有for循环,而是有一个knockout foreach。可能吗?它更好吗?这是可能的,而且可以说是更好的,因为我们正在稍微重新编写此处的淘汰功能。您的示例如何让$parent成为div中的viewModel,以便我可以执行删除和更新,现在在div中,$parent也是一个注释。对于这个给定的解决方案,如果我想在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);
            })();
        }
    
    }