14

私は親子ビューモデルオブジェクト構造を設定しておき、子の親ビューオブビューを更新する必要があります。私は基本的にはそうするための2つのパターンを作ってみた:子ビューモデルから親に対して観測可能なノックアウトを修正するためのパターン

1]を子供に親のプロパティの参照を渡し、子の中からプロパティを更新します。

var ParentViewModel = function(){ 
    var self = this; 
    this.selectedItem = ko.observable(); 
    this.child = ko.observable(new ChildViewModel(self.selectedItem)); 
} 

var ChildViewModel = function(parentSelectedItem){ 
    var self = this; 
    this.id = ko.observable(); 
    this.parentSelectedItem = parentSelectedItem; 
    this.select = function(){ 
     self.parentSelectedItem(self); 
    } 
} 

2]子どもの作成します親のメソッドを選択し、親を観測可能なものをローカルで参照してください。

var ParentViewModel = function(){ 
    var self = this; 
    this.selectedItem = ko.observable(); 

    var child = new ChildViewModel(); 
    child.select = function(){ 
     self.selectedItem(child); 
    } 
    this.child = ko.observable(child); 
} 

var ChildViewModel = function(){ 
    this.id = ko.observable(); 
} 

どちらのパターンも私をヒールで頭を上がらせません。最初のものは、プロパティ参照全体を子ビューモデルにプッシュし、2番目のビューは子のスコープの外に子の関数を定義します。

誰にも、この操作がきれいでテスト可能な方法でjavascriptでどのように達成できるかについての他のパタ​​ーン提案がありますか?あるいは、私は多かれ少なかれこれらの2つのオプションだけでつかまっていますか?

答えて

19

ノックアウトでこれを行う最も一般的なパターンは、子をとる親に「selectChild」メソッドを配置することです。ほとんどの場合、実際の子供は選択されていることを知る必要はありません。

バインドでは、$root.selectChildまたは$parent.selectChildにバインドできます。クリック/イベントバインドにバインドされたハンドラに渡される最初の引数は実際のデータ(KO 2.0)です。したがって、メソッドは親に存在し、子を最初の引数として受け取ることができます。この場合

var Item = function(id, name) { 
    this.id = id; 
    this.name = ko.observable(name);  
}; 

var ViewModel = function() { 
    var self = this; 
    this.items = ko.observableArray([ 
     new Item(1, "one"), 
     new Item(2, "two"), 
     new Item(3, "three") 
    ]); 

    this.selectedItem = ko.observable(); 

    this.selectItem = function(item) { 
     self.selectedItem(item); 
    };  
}; 

、あなたの結合は、次のようになります。

<ul data-bind="foreach: items"> 
    <li> 
     <a href="#" data-bind="text: name, click: $root.selectItem"></a> 
    </li> 
</ul> 

ここでは、jsFiddleである:http://jsfiddle.net/rniemeyer/anRsA/

あなたも、それをさらに簡素化することができます。 Observablesは関数であり、渡す最初の引数は値を設定するために使用されるため、selectItemメソッドを含めずに直接$root.selectedItemに直接バインドすることもできます(http://jsfiddle.net/rniemeyer/anRsA/1/のようになります)。私は通常、明示的に別のメソッドを使用して適切な名前(アクション)を与え、アイテムの設定前後に余分な処理が必要な場合に使用します。

$root$parentclickeventハンドラに最初引数​​としてデータを渡すために変化に伴って導入された)KO 2.0の前に、私はあなたがかなり提案最初の方法を使用するために使用されます。実際には、子プロパティ(this.parentSelectedItem)を作成しておらず、作成されたクロージャのためにファンクションで利用できるように、メソッドで直接parentSelectedItem(引数として渡された)参照を直接作成することはできません。

+0

ありがとうライアン、私はよく思った答えに感謝します。 – KodeKreachor

+0

私はこの回答のために+2ボタンが必要です – KodeKreachor

+0

私はあなたにもそれをプラスします:-)これを行うための非常にクリーンな方法。また、人々が望む子ビューモデルは、まったく別のモデル(その純粋なデータ)であることがよくあります。ときには、そのように我々がそれらを呼び出すものは、そのように考えるのは簡単です –

関連する問題