2012-02-10 7 views
6

Mam obecnie problemy z odświeżeniem interfejsu użytkownika, gdy otrzymuję nowe dane z serwera dla pojedynczego elementu, który znajduje się w obserwowalnym obiekcie obiektów opakowujących, który przechowuje obiekt z kilkoma obserwowalnymi obiektami .Nie mogę zaktualizować interfejsu użytkownika ze świeżymi obiektami danych

Rozważmy następujący:

var vm = { 
.... 
localEdited: ko.mapping.fromJS(new ItemWrapper(defaultModelSerialised)), 
selected: ko.observable(null), 
editItem: function(data) { 
    // clone a temporary copy of data for the dialog when opening (*.localEdited on dialog) 
    var clonedData = ko.toJS(data); 
    ko.mapping.fromJS(clonedData, null, this.localEdited); 

    // selected should now point to the item in the obserable array which will be refreshed 
    this.selected(data); 

    // open dialog... 
}, 
submitDialog: function(data) { 

    // submit data to server... 

    // (1) commit the data back to UI (new item is return in resp.entity from server) 
    vm.selected(new ItemWrapper(resp.entity)); 

    // at this point the UI isn't showing the updated value 

    // (2) however if I do this it reflects the data change in the UI 
    this.selected().Name("changed"); // updates the UI. 
} 

Może ktoś wyjaśnić dlaczego przechodzącą w ItemWrapper do vm.selected nie jest aktualizowanie UI, podczas gdy w (2) to działa. Nie chcę ustawiać każdej właściwości, jak w (2) dla każdej nieruchomości.

ItemWrapper wygląda tak:

function PoolWrapper(pool) { 
    this.Name = ko.observable(pool.Name); 

    // more properties... 
} 
+0

Czy wiążesz wszystko z vm.selected w html? Jeśli nie, dlaczego oczekujesz aktualizacji do UI w tym wierszu vm.selected (new ItemWrapper (resp.entity)); ? –

+0

Może uda ci się uzyskać coś w jsFiddle, aby zademonstrować? Byłoby łatwiej zobaczyć część twojego kodu. Zakładam, że może robisz 'with: selected' w twoim interfejsie lub używając szablonu przeciwko' selected'? –

+0

@RomanBataev: Nic nie jest bezpośrednio związane z vm.selected. W editItem() przekazywane dane pochodzą z ItemWrapper w obserservArray. Wybrana zmienna wskazuje następnie element w tablicy. Jak pokazuje punkt (2), jest on związany z interfejsem użytkownika podczas ładowania właściwości pojedynczo, ale nie przy przekazywaniu ItemWrapper do wybranej zmiennej(). – jaffa

Odpowiedz

6

OK-problem jest to, że klony skończyć z mapowania metadanych na nich i ostatecznie powoduje rekursji podczas próby wywoływania ko.mapping.fromJS.

Rozwiązaniem jest utworzenie klonów za pomocą ko.mapping.toJS zamiast ko.toJS, aby otrzymać czysty klon (bez mapowania metadanych).

Oto zaktualizowana skrzypce: http://jsfiddle.net/rniemeyer/tDDBp/

+0

Dzięki za to. Nie wiem, dlaczego ko.toJS zachowa dane odwzorowania, a plik ko.mapping.toJS nie. – jaffa

+0

ko.mapping.toJS specjalnie wie o opcjach mapowania i je usuwa, a ko.toJS nie ma pojęcia o wtyczce mapującej. –

0

Coś ja też natknęli się dzisiaj, że pomyślałem, że podzielę:

Jeśli można sklonować stosując:

var clone = ko.mapping.fromJS(ko.mapping.toJS(itemToClone)); 

Następnie klon będzie pozbawiony jakichkolwiek obliczalnych obserwowalnych obiektów. Będą one istnieć jako ostatnia wartość funkcji, ale przestaną funkcjonować jako obliczalne obserwowalne.

Jeśli pozycja jest złożony model z obliczonych obserwabli, które chcesz zachować na swoim klonie można wykonać następujące czynności:

var clone = ko.mapping.fromJS(ko.mapping.toJS(itemToClone), null, new itemModel()); 

Gdzie itemModel to skomplikowany wzór dla przedmiot zawierający swoje obliczone obserwable.

Powiązane problemy