【问题标题】:Updating Sub Properties in Knockout JS mapping plugin在 Knockout JS 映射插件中更新子属性
【发布时间】:2012-12-26 10:31:12
【问题描述】:

我遇到了带有分层视图模型的淘汰赛 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 而不是更新它。

【问题讨论】:

    标签: knockout.js knockout-mapping-plugin


    【解决方案1】:

    就我个人而言,我很喜欢创建这样的模型。这里的抽象更有意义。

    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.
    

    【讨论】:

    • 希望避免这种情况,因为所讨论的对象图很大并且比这更复杂,这只是其中的一部分,因此首先使用 ko.mapping 插件。
    • 同样在这个模型中,你如何支持取消更新(本质上是我的问题的根源)
    • 为什么需要克隆对象。只需将弹出窗口绑定到同一个对象。或者,如果您希望能够取消更新,只需保留对原始对象的引用,然后将克隆对象中的值更新为原始对象。
    • @TomasKirda 我确实需要支持取消。天气我在“保存”或“取消”时从克隆对象更新,我会遇到同样的问题!
    【解决方案2】:

    我不确定我是否完全理解你在做什么。

    但我试图在项目列表中执行撤消功能,我在数组上使用了这个:

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

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

    【讨论】:

      【解决方案3】:

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

      但是,对于新项目,我现在使用 knockout plugin

      【讨论】:

        猜你喜欢
        • 2012-02-08
        • 2012-09-25
        • 1970-01-01
        • 2014-04-12
        • 1970-01-01
        • 2015-01-17
        • 2012-12-18
        • 2012-01-30
        • 2014-04-29
        相关资源
        最近更新 更多