Javascript 触发按键、复选框或选择时将值保存到json对象中

Javascript 触发按键、复选框或选择时将值保存到json对象中,javascript,knockout.js,Javascript,Knockout.js,我有一个非常基本的动态表单,在其中我使用knockout.js框架。我可以根据需要实时添加或删除联系人。在textarea中保存json对象有点困难。在下面的函数中,self.save获取这些值并将它们放置在json对象中。然后textarea保存属性data bind='value:lastSavedJson',该属性保存json对象。我正在努力解决的棘手问题是,每次在输入字段、复选框或选择菜单上按下键时,都会触发更改。最初,这是通过一个按钮的触发来完成的。如何在每次触发键、复选框、选择菜单时

我有一个非常基本的动态表单,在其中我使用knockout.js框架。我可以根据需要实时添加或删除联系人。在textarea中保存json对象有点困难。在下面的函数中,self.save获取这些值并将它们放置在json对象中。然后textarea保存属性data bind='value:lastSavedJson',该属性保存json对象。我正在努力解决的棘手问题是,每次在输入字段、复选框或选择菜单上按下键时,都会触发更改。最初,这是通过一个按钮的触发来完成的。如何在每次触发键、复选框、选择菜单时将值保存在json对象中


我对您的viewmodels做了一些更改,所以它们的布局更好一些。另外,您会注意到我删除了jQUery位……原因如下。 1一般来说,如果您发现自己使用jQuery并在淘汰视图模型中引用dom,那么您做得不对/有一种更好的惯用方法,淘汰方法。这将使viewmodel与模板分开

2那永远不会按你想要的方式工作。Knockout将在它认为合适的时候添加和删除dom,jQuery将只绑定到运行查询时页面上存在的事件。有一种技术可以工作,但敲除实际上会干扰事件冒泡,这就是为什么上面的原因1非常相关。有关更多信息,如果您感到好奇,请查看并找出$input、select.CHANGETHANDER和$body之间行为的差异

然后,在您的视图中,在main模型中使用“with”,并以您提交的形式包装输入,或者避免在模板输入上加上名称,这样它们就不会与json数据一起提交。 另外,请确保在输入上使用valueUpdate绑定,以便立即对其进行序列化

<div data-bind="with:MainModel">
  <!--the rest of your template -->
<ul data-bind="foreach:contacts">
  <li>
    <label>First Name: 
      <input data-bind="value:firstName, valueUpdate:'afterkeydown'" />
    </label>
  </li>
</ul>
</div>
<form>
<textarea name="data" data-bind='value: serializedModel' rows='25' cols='60'></textarea>
<input type="hidden" name="serializedModel" data-bind="value:mainModelSerialized" />
</form>

这是伟大的,但嗯,似乎无法得到它的工作。你能提供一个简单的答案吗。结尾处可能缺少括号。缺少};在ko.applyBindings之前的modelWithSerializedData的末尾声明以及一些;联系人模型声明中缺失;否则,这种方法应该有效
var initialData = [{
    firstName: "Jenny",
    lastName: "LaRusso",
    phone: "(555) 121-2121",
    alt_phone: "(555) 123-4567",
    main1: false,
    main2: true    
}, {
    firstName: "Sensei",
    lastName: "Miyagi",
    phone: "(555) 444-2222",
    alt_phone: "(555) 999-1212",
    main1: true,
    main2: false
}];
var ContactModel = function(contact) {
  var self = this;
  self.firstName = ko.observable(contact.firstName);
  self.lastName = ko.observable(contact.lastName);
  //what is the point of the phone observable when there is an array of phones?
  //the data structure doesn't match either - self.phone contains a phone number, and
  //self.phones contains objects with a 'number' property
  self.phone = ko.observable(contact.phone);
  //array for all the phones, initialize it with the passed in data or an empty array
  self.alt_phone = ko.observable(contact.alt_phone);
  self.phones = ko.observableArray(contact.phones || []);
  self.main1 = ko.observable(contact.main1);
  self.main2 = ko.observable(contact.main2);
}
var ContactsModel = function (contacts) {
    var self = this;
    self.contacts = ko.observableArray(ko.utils.arrayMap(contacts || [], function(contact) { return new ContactModel(contact)}));

     //this ajax call is going to override the default data passed in via the contacts parameter...Is that what's supposed to happen?
     $.getJSON("functions/getPerson.php", function(allData) {
          var initialData = $.map(allData, function(person) { return new ContactModel(person) });
          console.log(self.contacts(initialData));
    });

    self.addContact = function () {
        self.contacts.push(new ContactModel());
    };

    self.removeContact = function (contact) {
        self.contacts.remove(contact);
    };

    //your contacts didn't have a phone array, so I added one to make this function work.
    self.addPhone = function (contact) {
        contact.phones.push({
            number: ""
        });
    };

    self.removePhone = function (phone) {
        $.each(self.contacts(), function () {
            this.phones.remove(phone)
        })
    };

};

var mainModel = new ContactsModel(initialData);
var modelWithSerializedData = {
  MainModel:mainModel,
  mainModelSerialized: ko.computed(function() { 
      return ko.toJSON(mainModel);
  })
}
ko.applyBindings(modelWithSerializedData);
<div data-bind="with:MainModel">
  <!--the rest of your template -->
<ul data-bind="foreach:contacts">
  <li>
    <label>First Name: 
      <input data-bind="value:firstName, valueUpdate:'afterkeydown'" />
    </label>
  </li>
</ul>
</div>
<form>
<textarea name="data" data-bind='value: serializedModel' rows='25' cols='60'></textarea>
<input type="hidden" name="serializedModel" data-bind="value:mainModelSerialized" />
</form>