17

私はKnockoutJSが初めてで、プラグインko.observableArray()によって作成されたように、生成されたオブジェクトに追加のプロパティとメソッドを追加しようとして立ち往生しています。mapping


ここに私がいるところです:

  • 私はJSON配列を持っていますUsers
  • ko.observableArray()マッピングプラグインで作成しました
  • それぞれのテーブル行を作成するテンプレートを持っていますがUser、これまでのところとても良いです:o)


これが私がやろうとしていることです:

それぞれUserにというプロパティがあります'IsActive'-このプロパティを切り替える各オブジェクトdata-bindのメソッドへのクリック イベントが必要です。User'IsActive'

この質問は有望に見えましたが、ビューモデル全体を JS で宣言する必要があるのは不必要な重複のようです (それが私がしなければならない方法でない限り!) - 生成されたオブジェクトを拡張することは可能ですか?

私は、追加のプロパティまたはメソッドを宣言し、mapping生成されたオブジェクトを拡張する方法があるこれらの線に沿ってもっと考えていましたが、この記事は、生成された配列内のオブジェクトを拡張するのではなく、単一のオブジェクトに関係しています。


コードは次のとおりです: http://jsfiddle.net/yZkSf/2/ (JS fiddle ではまだ動作していませんが、動作するようになったらこのリンクを更新します)。

ご協力ありがとうございました

4

3 に答える 3

13

検討できるオプションがいくつかあります。

-1 つは、createコールバックを使用して、「ユーザー」オブジェクトの作成方法を制御することです。オブザーバブルを自分で定義して追加機能を追加するか、個々のユーザー オブジェクトでマッピング プラグインを呼び出して追加機能を追加することができます。

次のようになります: http://jsfiddle.net/rniemeyer/fkVaK/

-それ以外の場合は、ビューモデルに「トグル」関数を配置してから、「ユーザー」オブジェクトをそれに渡すことができます。

1.3 での良い方法は、ko.dataForjQuery の live/delegate/on イベント委任機能のようなものと一緒に使用することです。のようになります: http://jsfiddle.net/rniemeyer/FkjNr/

//unobtrusive event handler
$(".toggle").live("click", function() {
    var user = ko.dataFor(this);
    if (user) {
       viewModel.toggleIsActive(user);
    }
});

イベント委任を使用したくない場合は、次のような匿名関数を使用してアイテムを直接渡すことができます: http://jsfiddle.net/rniemeyer/GpQtN/

EDIT:2.0以降、クリック/イベントバインディングを使用すると、現在のデータが自動的にハンドラーに渡されるため、次のことができます:

<a href="#" data-bind="click: $root.toggleIsActive"><span data-bind="text: IsActive"></span></a>
于 2011-12-06T15:58:00.753 に答える
4

これは、あなたとライアンの両方の回答を使用して思いついたものです...うまくいくようです。これが良いアプローチであるかどうか、私はノックアウトに慣れていないので、フィードバックを残してください.

JS:

$(function() {
    $.get("users/getUsers", function(r){
        var vm = ko.mapping.fromJS(r, {
            users: {
                create: function(user){
                    var methods = {
                        toggleIsActive: function(u){u.IsActive(!u.IsActive());},
                        foo: function(u){console.log(u);},
                        bar: function(u){/*whatever*/},   
                    }
                    return $.extend(ko.mapping.fromJS(user.data), methods);
                }
            }
        });
        ko.applyBindings(vm);
    }, 'json');
});

ドム:

<!-- ko foreach: users -->
   <a href="#" data-bind="click: toggleIsActive"><span data-bind="text: IsActive"></span></a>
<!-- /ko -->
于 2012-06-27T06:27:46.470 に答える
0

私はそれを行う方法を見つけましたが、それは、作成された配列内の生成されたオブジェクトをループすることを意味します.追加のループなしで同じ結果を達成する方法を好む..

編集: RP Niemeyerが彼の答えで示唆しているように! ;o)

とにかく、既存のオブジェクトにプロパティを追加する 1 つの方法は、jQuery extends()を使用してオブジェクトを結合することです。

まず、追加のプロパティと関数を新しいオブジェクトで宣言します。

var userModel = {
    toggleIsActive: function() {
        console.log('toggleIsActive called: before: ' + this.IsActive());
        this.IsActive(!this.IsActive());
        // todo: save!
        console.log('toggleIsActive called: after: ' + this.IsActive());
    }
}

次に、呼び出しの後、呼び出しko.mapping.fromJS()前にko.applyBindings()、生成された配列内のオブジェクトをループして拡張します。

viewModel.users = ko.mapping.fromJSON(/* get JSON */);

for (var i = 0; i < viewModel.users().length; i++) {
    $.extend(viewModel.users()[i], userModel);
}

ko.applyBindings(viewModel);
于 2011-12-06T16:01:36.513 に答える