Обновление дополнительных свойств в подключаемом модуле сопоставления Knockout JS

У меня проблема с нокаутом js и плагином сопоставления с иерархической моделью представления.

Моя модель представления устроена примерно так:

VM = {
    members:[
        {
            name:"name 1",
            volunteering:[{...},{...},{...}]
        },
        {
            name:"name 1",
            volunteering:[{...},{...},{...}]
        }
    ]
}

Каждый участник находится на вкладке, и каждая вкладка имеет сетку волонтерской деятельности. При нажатии на элемент в сетке открывается диалоговое окно для редактирования волонтерской деятельности. На этом этапе я клонирую объект, чтобы упростить функцию «отменить редактирование».

var Volunteer = {};
var koContext=ko.contextFor(this);
Volunteer = ko.mapping.toJS(koContext.$data);  //plain js volunteer
Volunteer.index=koContext.$parent.EventVolunteers().indexOf(koContext.$data);  //index of volunteer in member volunteer array
ko.applyBindings(ko.mapping.fromJS(Volunteer),$("#dialog-EditVolunteer")[0]); //bind new volunteer obj to dialog

До этого момента кажется, что все в порядке, нажатие кнопки «Сохранить» в диалоговом окне вызывает проблему.

var volunteer = ko.mapping.toJS(ko.contextFor(this).$data);
ko.mapping.fromJS(volunteer,{},ko.contextFor(currentTab).$data.EventVolunteers()[volunteer.index]);

В этот момент свойства обновляются в модели представления, но не в сетке на главном экране.

Похоже, что ko.mapping.fromJS заменяет наблюдаемое, а не обновляет его.


person stevenrcfox    schedule 11.01.2013    source источник


Ответы (3)


Лично я фанат таких моделей. Абстракция здесь просто имеет больше смысла.

function VolunteerInfo(data){
  var self = this;
  self.activitiesName = ko.observable(data.name);
  // any other info not all of it has to be mapped 
  // unless you plan on sending it back.
}
function MembersInfo(data){
  var self = this;
  self.name = ko.observable(data.name)// w.e it is labeled as under json
  self.volunteering = ko.observableArray([]);
  var mappedVolunteers = $.map(data.volunterring, function(item){
    var volunteer = new VolunteerInfo(item);
    return volunteer;
  });
  self.volunterring(mappedVolunteers);
}
function VM(){
  var self = this;
  self.members = ko.o
  var request = $.getJSON("webservice address");
  request.done(function () {
    var mappedMembers = $.map(data.volunterring, function(item){
      var member = new MemberInfo(item);
      return member;
    });
    self.members(mappedMembers);
  }
}
// apply bindings to VM ect ect.
person Calvin    schedule 17.01.2013
comment
Надеялся избежать этого, поскольку рассматриваемый граф объектов большой и более сложный, чем этот, это только его сегмент, поэтому в первую очередь используется плагин ko.mapping. - person stevenrcfox; 18.01.2013
comment
Также в этой модели, как вы поддерживаете отмену обновлений (по сути, источник моей проблемы) - person stevenrcfox; 18.01.2013
comment
Зачем вам нужно клонировать объект. Просто привяжите всплывающее окно к тому же объекту. Или, если вы хотите иметь возможность отменить обновления, просто сохраните ссылку на исходный объект, а затем обновите значения из клонированного объекта до исходного. - person Tomas Kirda; 20.01.2013
comment
@TomasKirda Мне нужно поддержать отмену. Погода, которую я обновляю из клонированного объекта при «сохранении» или «отмене», у меня будет такая же проблема! - person stevenrcfox; 24.01.2013

Я не уверен, что полностью понимаю, что вы делаете.

Но я пытался выполнить функцию отмены в списке элементов и использовал это в массиве:

observableArray.replace(newData, ko.mapping.fromJS(original))

Я получаю новые данные в качестве аргумента обработчика кликов.

Когда я храню оригинал, у меня в основном это:

        //Dupe check
        self.undoCache.Emails.pop(jQuery.grep(self.undoCache.Emails, function (element, index) { return element.Id == data.Id(); })[0]);
        //Store original
        self.undoCache.Emails.push(ko.mapping.toJS(data));

«Электронные письма» — это объекты, которые я редактирую. Я храню только исходные данные, а не наблюдаемые. Это позволило мне использовать replace. Я не уверен, насколько это правильно само по себе, но отмена работает для меня.

person BoB    schedule 22.02.2013

Мое окончательное решение в этом случае состояло в том, чтобы установить свойства исходной виртуальной машины с отредактированными значениями из «клонированной» модели представления.

Однако для новых проектов я теперь использую плагин нокаута.

person stevenrcfox    schedule 24.06.2013