2013-01-11 232 views
2

我有一个分层视图模型更新子属性

我的视图模型在一定程度上构成这样与淘汰赛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取代了observable而不是更新它。

回答

0

在这种情况下,我最终的解决方案是使用“克隆”视图模型中的编辑值设置原始VM上的属性。

对于新的项目不过,我现在用一个knockout plugin

0

就我个人而言,我是创建模型的粉丝。这里的抽象只是更有意义。

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. 
+0

希望避免这是有问题的对象图大,比这更复杂,这只是其中的一个部分,因此使用ko.mapping的首先插件。 – stevenrcfox

+0

同样在这个模型中,你如何支持取消更新(本质上是我的问题的来源) – stevenrcfox

+0

为什么你需要克隆对象。只需将弹出窗口绑定到同一个对象。或者,如果您希望能够取消更新,请保留对原始对象的引用,然后将克隆对象的值更新为原始对象。 –

0

我不确定我完全明白你在做什么。

但我试图做的项目列表撤消功能,我用这个阵列上:

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

的“电子邮件”是我编辑的对象。我只存储原始数据,而不是可观察数据。这让我可以使用替换。我不确定这本身有多正确,但取消了我的作品。