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 の内容を、作成された各項目のテンプレートとして使用する場合は、さらに 2 つの手順が必要です。

  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 }メソッドから戻ることで、div のコンテンツがノックアウトによって処理されるのを防ぐ必要があることに注意してくださいinit

これが更新された例です

于 2012-06-14T11:36:33.520 に答える