14

Mam skonfigurowaną strukturę obiektu modelu nadrzędnego podrzędnego i trzeba zaktualizować obserwowalny obiekt nadrzędny z podrzędnego. Ja po prostu pochodzić z dwóch wzorów za to:Wzorzec do modyfikowania nokautu obserwowalnego na obiekcie nadrzędnym z modelu widoku podrzędnego

1] Przepuścić odniesienie nieruchomości macierzystej dla dziecka i zaktualizuj właściwość z poziomu dziecka:

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] Tworzenie dziecka wybierz metodę na obiekcie nadrzędnym i odniesienie do obiektu macierzystego obserwowalnego lokalnie:

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

Żaden z tych wzorów nie wysyła mi po piętach. Pierwszy przesuwa cały odnośnik właściwości do modeli widoku dzieci, drugi definiuje funkcję dziecka poza zakresem funkcji podrzędnej.

Czy ktoś ma jakieś sugestie dotyczące schematu, w jaki sposób można uzyskać tę operację w javascript w czysty i sprawdzalny sposób? Czy mniej lub bardziej utknąłem z tymi dwoma opcjami?

Odpowiedz

19

Najczęściej stosowanym wzorem w Knockout jest umieszczenie na rodzicu metody "selectChild", która obejmuje dziecko. W większości przypadków rzeczywiste dziecko nie musi wiedzieć, że jest wybierane.

Następnie w oprawce można powiązać z $root.selectChild lub $parent.selectChild. Pierwszy argument przekazany do handler'a powiązanego z wiązaniem click/event jest rzeczywistymi danymi (w KO 2.0), więc twoja metoda może żyć na rodzica i odebrać dziecko jako pierwszy argument.

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

W tym przypadku swój wiążący będzie wyglądać następująco:

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

Oto ona w jsFiddle: http://jsfiddle.net/rniemeyer/anRsA/

Można nawet uprościć go dalej. Obserwowalne są funkcje i pierwszy argument, który im przekazujesz, służy do ustawiania ich wartości, więc możesz nawet zdecydować, aby nie włączać metody selectItem i po prostu wiązać bezpośrednio z $root.selectedItem (wyglądałoby to tak:). Zwykle używam osobnej metody jawności, aby nadać jej właściwą nazwę (działanie), oraz w przypadku, gdy istnieje dodatkowe przetwarzanie, które należy wykonać przed lub po ustawieniu elementu.

Przed KO 2.0 (gdzie $root i $parent zostały wprowadzone wraz ze zmianą przekazać dane jako pierwszy arg do click i event teleskopowe), ja używałem pierwszy sposób, że sugerowane całkiem sporo. Jedną z rzeczy, które możesz tam zrobić, jest to, że nie tworzysz właściwości podrzędnej (this.parentSelectedItem) i po prostu odwołujesz się do parentSelectedItem (która została przekazana jako argument) bezpośrednio w metodzie select, ponieważ będzie ona dostępna w funkcji z powodu zamknięcia, które zostało utworzone .

+0

Dzięki Ryan, doceniam dobrze przemyślaną odpowiedź. – KodeKreachor

+0

Potrzebuję przycisku +2 do tej odpowiedzi. – KodeKreachor

+0

Będę go również dla ciebie :-) Bardzo czysty sposób to zrobić. Ponadto, często rezygnuje z modelu widoku podrzędnego, który ludzie chcą, to naprawdę tylko inny model (to tylko czyste dane). Czasami łatwiej jest o nim myśleć w ten sposób, niezależnie od tego, jak je nazywamy. –

Powiązane problemy