0

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

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

您能否帮助我正确地了解我应该如何构建它。我还没有看到这样做的 bindingHanlder。

我想要的是这样的东西。

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

1 回答 1

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

    };

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

这是一个更新的示例

于 2012-06-14T11:36:33.520 回答