2012-04-04 12 views
14

Ho una struttura di struttura del modello di visualizzazione padre-figlio e devo aggiornare un osservabile sul genitore dal bambino. Sono fondamentalmente venuta in mente due modelli per farlo:Schema per la modifica del knockout osservabile sul genitore dal modello di vista figlio

1] passare un riferimento della proprietà genitore al bambino e aggiornare la proprietà all'interno del bambino:

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] Creare il figlio di selezionare il metodo sul genitore e fare riferimento al genitore osservabile localmente:

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

Nessuno di questi motivi mi fa perdere la testa. Il primo spinge l'intero riferimento di proprietà in modelli di vista figli, il secondo definisce la funzione di un bambino al di fuori dell'ambito del bambino.

Qualcuno ha altri suggerimenti di modello su come questa operazione potrebbe essere raggiunta in javascript in modo pulito e testabile? O sono più o meno bloccato con solo queste due opzioni?

risposta

19

Il modello più comune per eseguire questa operazione in Knockout consiste nel mettere un metodo "selectChild" sul genitore che accetta un figlio. Nella maggior parte dei casi, il bambino reale non ha bisogno di sapere che è stato selezionato.

Quindi nella rilegatura, è possibile eseguire il binding a $root.selectChild o $parent.selectChild. Il primo argomento passato a un gestore associato al collegamento di click/evento è il dato reale (in KO 2.0), quindi il tuo metodo può vivere sul genitore e ricevere il bambino come primo argomento.

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

In questo caso, il legame sarebbe simile:

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

Qui è in jsFiddle: http://jsfiddle.net/rniemeyer/anRsA/

Si può anche semplificare ulteriormente. Le funzioni osservabili sono le funzioni e il primo argomento che si passa a loro viene utilizzato per impostare il loro valore, in modo da poter scegliere di non includere il metodo selectItem e semplicemente associare direttamente allo $root.selectedItem (potrebbe essere: http://jsfiddle.net/rniemeyer/anRsA/1/). Di solito uso un metodo separato per essere esplicito, per dargli un nome appropriato (azione), e nel caso ci sia un'ulteriore elaborazione che deve essere eseguita prima o dopo aver impostato l'oggetto.

Prima KO 2.0 (dove $root e $parent sono stati introdotti con il cambiamento per passare i dati come il primo arg a click e event gestori), ho utilizzato il primo metodo che hai suggerito un bel po '. Una cosa che puoi fare lì non è in realtà creare la proprietà child (this.parentSelectedItem) e fare semplicemente riferimento allo parentSelectedItem (che è stato passato come argomento) direttamente nel metodo select, poiché sarà disponibile nella funzione a causa della chiusura creata .

+0

Grazie Ryan, apprezzo la risposta ben ponderata. – KodeKreachor

+0

Ho bisogno di un pulsante +2 per questa risposta – KodeKreachor

+0

Lo farò anche per te :-) Modo molto pulito per farlo. Inoltre, esci spesso dal modello di vista del bambino che le persone vogliono in realtà è solo un altro modello (sono solo dati puri). A volte è più facile pensarla così, qualunque cosa li chiamiamo –