触发按键,复选框或选择时将值保存到json对象中 [英] Saving values into a json object when keypress, checkbox or select is triggered

查看:94
本文介绍了触发按键,复选框或选择时将值保存到json对象中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个非常基本的动态形式,其中我使用了基因敲除框架.我能够根据需要实时添加或删除联系人.我在将json对象保存在文本区域内时遇到了一些困难.在self.save下面的函数中,获取值并将其放置在json对象中.然后,textarea保留属性data-bind=’value: lastSavedJson’,该属性保留json对象.我努力的棘手部分是每次在输入字段,复选框或选择菜单上触发keyup, change时都执行此操作.最初,这是通过触发按钮来完成的.每次触发键,复选框和选择菜单时,如何将值保存在json对象中? JSFIDDLE

I have a very basic dynamic form in which I am using knockout.js framework. I am able to add or remove contacts as needed in real time. I am having a little difficulty saving the json object inside a textarea. In the function below self.save takes the values and places them inside a json object. Then the textarea holds attribute data-bind=’value: lastSavedJson’, which holds the json object. The tricky part that I am struggling is doing this every time keyup, change is trigger on a input field, checkbox or select menu. Initially this was done with trigger of a button. How can I save the values inside a json object every time a key, checkbox, select menu is triggered? JSFIDDLE

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 ContactsModel = function (contacts) {
    var self = this;
    self.contacts = ko.observableArray([]);

    ko.utils.arrayForEach(contacts, function (contact) {
        self.contacts.push({
            firstName: contact.firstName,
            lastName: contact.lastName,
            phone: contact.phone,
            alt_phone: contact.alt_phone,
            main1: ko.observable(contact.main1),
            main2: ko.observable(contact.main2)
        });
    });

     $.getJSON("functions/getPerson.php", function(allData) {
          var initialData = $.map(allData, function(person) { return new ContactsModel(person) });
          console.log(self.contacts(initialData));
    });

    self.addContact = function () {
        self.contacts.push({
            firstName: "",
            lastName: "",
            phone: "",
            alt_phone: "",
            main1: false,
            main2: false
        });
    };

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

    self.addPhone = function (contact) {
        contact.phones.push({
            number: ""
        });
    };

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

    $("input,checkbox,selct").bind('change keyup', function() {
        self.save = function () {
           self.lastSavedJson(JSON.stringify(ko.toJS(self.contacts), null, 2));         
        };
    });


    self.lastSavedJson = ko.observable("");

};


ko.applyBindings(new ContactsModel(initialData));

推荐答案

我对您的视图模型进行了一些更改,因此它们的布局更好一些.另外,您会注意到我删除了jQUery位...这就是原因. 1)通常,如果您发现自己使用jQuery并引用了剔除视图模型中的dom,那么您做错了/有一种更好的方法 idiomatically ,即剔除方法.这样可以将视图模型与模板分开.

I made some changes to your viewmodels, so they're laid out a bit nicer. Also, you'll notice I removed the jQUery bit...here's why. 1) In general, if you find yourself using jQuery and referencing the dom inside of a knockout viewmodel, you're doing it wrong / there is a better way to do it idiomatically, the knockout way. This keeps your viewmodel separate from your templates.

2)那将永远无法按照您想要的方式工作.淘汰赛将根据需要添加和删除dom,并且jQuery仅绑定到查询运行时页面上存在的事件.可以使用一种技术,但敲除实际上会干扰事件冒泡,这就是上述原因1与之非常相关的原因.有关更多信息,如果您感到好奇,请查看 jQuery on 并进行计算找出$("input,select").change(changeHandler)$("body").on('change','input,select',changeHandler);

2) That would never work the way you wanted it to. Knockout is going to add and remove bits of dom as it sees fit, and jQuery will only bind to events that exist on the page at the moment the query is ran. There is a technique that could work, but knockout actually interferes with event bubbling, which is why reason #1 above is very pertinent. For more info, if you're curious, check out jQuery on and figure out the difference in behavior between $("input,select").change(changeHandler) and $("body").on('change','input,select',changeHandler);

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

,然后在您的视图中,使用"with"进入主模型,然后将输入仅包装在您提交的表单中,或者避免在模板输入中放置名称,以免它们与json数据一起提交. 另外,请确保在输入中使用valueUpdate绑定,以便立即对其进行序列化.

and then in your view, get at the mainmodel with a 'with', and wrap just the input in the form you're submitting OR avoid putting names on your template inputs so they don't get submitted with the json data. Also, make sure that you use the valueUpdate binding on your inputs so that it gets serialized immediately.

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

这篇关于触发按键,复选框或选择时将值保存到json对象中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆