Knockout.js актуализира модел на изглед

При зареждане на страницата конвертирам JSON данни, за да видя модел като този

var jsonField = '#' + '<% = hdnField.ClientID  %>';

                    jsonModel= {
                       availables: ko.observableArray([])
                   };

                 
                   var valueField = $(jsonField)[0].value;
                   var arrayGroup = $.parseJSON(valueField);

                   jsonModel.availables = ko.viewmodel.fromModel(arrayGroup);
                  
                  var block=$('#availabilitiesBlock')[0];
                   ko.applyBindings(jsonModel,block);

След като страницата се зареди, извиквам ajax сървърна функция, за да актуализирам този модел на изглед.

В tha ajax success call back съм написал като

 var updatedModel = {
                availables: ko.observableArray([])

            };
            updatedModel.availables = ko.viewmodel.fromModel(data.d);

Когато се опитам да актуализирам модела на изгледа с този актуализиран модел, целият ми модел става празен

Опитах следните методи

  1. Избута data.d в наблюдавания oldModel.availables. Когато натискам данните, обектите на масива не се преобразуват като наблюдаеми, но елементите се добавят към масива на наличните. Докато в началото (докато страницата се зарежда), обектите бяха преобразувани без проблеми.

  2. Опитах се да актуализирам директно моделите на изглед и в този случай целият модел става празен

    ko.viewmodel.updateFromModel(oldModel, updatedModel);

Фрагмент от стар модел

Стар модел

Фрагмент от актуализиран модел

Актуализиран модел

Както казах, когато избутах директно обектите на масива (data.d), наблюдаемите не се създават автоматично, както в първия случай преди ajax.

Защо се случва това, когато логиката е същата? Използвам http://coderenaissance.github.io/knockout.viewmodel/ за картографиране обекти автоматично.

Всякакви насоки ще бъдат полезни


person Rohith Nair    schedule 09.07.2013    source източник


Отговори (1)


Rohith, отговорът тук ще зависи от това какво връщате от вашето ajax повикване.

Вместо да създавам updateModel, вярвам в връщането от вашето ajax повикване, което искате

ko.viewModel.updateModel(jsonModel.availables, data.d);

Ако вашият data.d, върнат от извикването на Ajax, не се нуждае от специално картографиране (т.е. това е просто масив от обекти, които не се нуждаят от наблюдаеми), можете просто да актуализирате вашия модел директно

//ko.viewModel.updateModel(jsonModel.availables, data.d);
jsonModel.availables(data.d);

Основният проблем, с който се сблъсквате, е, че губите наблюдаемото, към което е обвързан изгледът ви. Вие губите jsonModel.availables, като го презаписвате или като го игнорирате и актуализирате различен модел (updateModel в този случай).

Работя върху публикация в блог относно точно този проблем при работа с AJAX, но можете да видите част от проблема, който имате в третия раздел на тази публикация: http://ryanrahlf.com/getting-started-with-knockout-js-3-things-to-know-on-day-one/

Надявам се това да помогне!

person Ryan Rahlf    schedule 09.07.2013
comment
на място :) В крайна сметка използвах ko.viewModel.updateModel(jsonModel.availables, data.d); но това кара потребителския ми интерфейс да виси поради по-дълго време за изпълнение на скрипта - person Rohith Nair; 09.07.2013
comment
Когато видите дълго време на изпълнение при промяна на наблюдаем масив, проверете за сложни процеси, които се изпълняват на всеки елемент (персонализирани обвързвания?) или изчисления на нокаут, които се преизчисляват за всеки елемент. - person Ryan Rahlf; 09.07.2013
comment
@RyanRahlf Ще работи ли това с плъгина за картографиране? Открих, че трябва да извикам applybindings вътре в обратното извикване на моя ajax. В противен случай моделът не се актуализира. Мисля, че включването на картографиране нарушава абонираните елементи и не може да го актуализира. stackoverflow.com/questions/21558075/ - person Vyache; 05.02.2014
comment
@Vyache, не трябва да извиквате applyBindings отново след извикване на ajax. Тази публикация в блог може да помогне: ryanrahlf.com/ - person Ryan Rahlf; 06.02.2014