22

observableArray 内で項目を 1 つ左に移動するボタンがあります。私は次の方法でそれをやっています。ただし、欠点は、categories()[index] が配列から削除されるため、そのノードでの DOM 操作 (私の場合は jQuery 検証による) が破棄されることです。

DOM ノードを保持するために、一時変数を使用せずに 2 つのアイテムを交換する方法はありますか?

    moveUp: function (category) {
        var categories = viewModel.categories;
        var length = categories().length;
        var index = categories.indexOf(category);
        var insertIndex = (index + length - 1) % length;

        categories.splice(index, 1);
        categories.splice(insertIndex, 0, category);
        $categories.trigger("create");
    }
4

4 に答える 4

35

moveUpワンステップでスワップを行う私のバージョンは次のとおりです。

moveUp: function(category) {
    var i = categories.indexOf(category);
    if (i >= 1) {
        var array = categories();
        categories.splice(i-1, 2, array[i], array[i-1]);
    }
}

ただし、それでも問題は解決しません。Knockout はスワップを削除と追加のアクションとして認識し続けるからです。ただし、Knockout がアイテムの移動をサポートするには未解決の問題があります。更新:バージョン 2.2.0 の時点で、Knockout は移動されたアイテムを認識し、foreachバインディングはそれらを再レンダリングしません。

于 2012-05-17T05:32:07.373 に答える
0

アイテムにjQueryのドラッグアンドドロップが必要だったのと同じような問題がありました。私の解決策は、knockoutjsテンプレートを使用して、beforeRemoveイベントとafterAddイベントをモデルにバインドすることでした。個人クラス/関数も単純なノックアウトビューモデルです。

以下の例では、.draggable()を使用していますが、検証を簡単に使用できます。observableArrayを操作するための独自のコードを追加すれば、準備は完了です。

HTML:

<div data-bind="template: {foreach:attendeesToShow, beforeRemove:hideAttendee, afterAdd:showAttendee}">
    <div class="person">
        <img src="person.jpg" alt="" />
        <div  data-bind="text: firstName" ></div>
        <div class="deleteimg" data-bind="click:$parent.removeAttendee" title="Remove"></div>
    </div>
</div>

ViewModel:

var ViewModel = function () {
    var self = this;
    var at = [new Person('First', 'Person', 'first@example.com'),
                    Person('Second', 'Person', 'second@example.com')
                ];
    self.attendees = ko.observableArray(at);

    self.removeAttendee = function (attendee) {
        self.attendees.remove(attendee);
    };

    this.showAttendee = function (elem) {
        if (elem.nodeType === 1) {
    $(elem).hide().show("slow").draggable();//Add jQuery functionality 
        }
    };
    this.hideAttendee = function (elem) {
        if (elem.nodeType === 1) {
            $(elem).hide(function () {
                $(elem).remove();
            });
        }
    };
};

ko.applyBindings(new ViewModel());
于 2012-04-24T07:55:03.260 に答える
0

moveup の彼のバージョンのMichael Bestに感謝します。

私のバージョンの moveDown

moveDown: function(category) {
    var array = categories();
    var i = categories.indexOf(category);
    if (i < arr.length) {
        categories.splice(i, 2, array[i + 1], array[i]);
    }
}
于 2014-11-04T02:02:01.340 に答える