简体   繁体   English

剔除-如何订阅多个下拉菜单(选择)并绑定到模型

[英]knockout - how to subscribe for multiple dropdown menus (select) and bind to a model

SO lovers and javascript developers, SO爱好者和JavaScript开发人员,

How can I bind multiple dropdowns to a model and subscripe its' change events individually for each dropdown? 如何将多个下拉菜单绑定到模型并为每个下拉列表分别订阅其更改事件?

I have a basic form for that.. You can see it live in jsFiddle: http://jsfiddle.net/2Mnr3/7/ 我有一个基本的形式。您可以在jsFiddle中看到它: http : //jsfiddle.net/2Mnr3/7/
Why all select fields changes together when I select one? 当我选择一个字段时,为什么所有选择字段都一起改变? How can I do it in individually way? 我该如何单独进行?

Here it's my HTML: 这是我的HTML:

<div class='liveExample'> 

<h2>Orders</h2>
<div id='contactsList'>
    <table class='contactsEditor'>
        <tr>
            <th>First Name</th>
            <th>Last Name</th>
            <th>Service</th>
        </tr>
        <tbody data-bind="foreach: contacts">
            <tr>
                <td>
                    <input data-bind='value: firstName' />
                    <div><a href='#' data-bind='click: $root.removeContact'>Delete</a></div>
                </td>
                <td><input data-bind='value: lastName' /></td>
                <td>
                    <table>
                        <tbody data-bind="foreach: services">
                            <tr>

                                <td>

                                    <select data-bind='options: catalog, value: $root.selectedId, optionsText: "name", optionsCaption: "Select..."'> </select>
                                </td>

                                <td>
                                    <div data-bind="visible: $root.selectedId()">
                                        <span data-bind='text: $root.selectedId.price'> </span>
                                        <!--<span data-bind='text: "asd"'> </span>-->
                                    </div>
                                <td>

                                <a href='#' data-bind='click: $root.removeService'>Delete</a></td>
                            </tr>
                        </tbody>
                    </table>
                    <a href='#' data-bind='click: $root.addService'>Add service</a>
                </td>
            </tr>
        </tbody>
    </table>
</div>

<p>
    <button data-bind='click: addContact'>Add customer </button>
    <button data-bind='click: save, enable: contacts().length > 0'>JSON</button>
</p>

<textarea data-bind='value: lastSavedJson' rows='5' cols='60' disabled
          ='disabled'> </textarea>

And Javascript Code with Knockout library: 和带有Knockout库的Javascript代码:

function formatCurrency(value) {
    console.log(value);
    return value;
}

var serviceTypes = [
        { name: "Service One", id: "1", price: "10 USD"},
        { name: "Service Two", id: "2", price: "9 USD"},
        { name: "Service Three", id: "3", price: "25 USD"},
        { name: "Service Four", id: "4", price: "42 USD"}
      ];

var initialData = [
{ firstName: "John", lastName: "Carter", services: [{ catalog: serviceTypes, id: 0 }, { catalog: serviceTypes, id: 2 }]
}
];

   function ContactsModel(contacts) {
    var self = this;
    self.contacts = ko.observableArray(ko.utils.arrayMap(contacts, function(contact) {
        return { id: contact.id, firstName: contact.firstName, lastName: contact.lastName, services: ko.observableArray(contact.services) };
    }));


self.serviceTypes = ko.observableArray(serviceTypes);
self.selectedId = ko.observable('1');

self.selectedId.subscribe(function(item){
    return ko.utils.arrayFirst(serviceTypes, function(service) {
        return service;
    });
});

self.addContact = function() {
    self.contacts.push({
        firstName: "",
        lastName: "",
        services: ko.observableArray([
            {
                catalog: this.serviceTypes,
            }])
    });
};

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


self.addService = function(contact) {
    contact.services.push({
        catalog: self.serviceTypes,
    });
};

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

self.save = function() {
    self.lastSavedJson(JSON.stringify(ko.toJS(self.contacts), null, 2));
};

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

ko.applyBindings(new ContactsModel(initialData));

You are sharing same observable($root.selectedId) instead of this every catalog should have there own copy of selectedId. 您共享的是相同的observable($ root.selectedId),而不是每个,每个目录都应该有自己的selectedId副本。 for that you can use constructor function eg, 为此,您可以使用构造函数,例如

function Catalog(serviceTypes, d) {
   this.catalog = serviceTypes;
   this.selectedId = ko.observable(d || null);
   this.selectedId.subscribe(function (item) {
     //Subscriber Handler
   });
}
var initialData = [{
  firstName: "John",
  lastName: "Carter",
  services: [new Catalog(serviceTypes, 1), new Catalog(serviceTypes, 2)]
}];

addContact and addService function are also changed. addContact和addService函数也被更改。

 self.addContact = function () {
    self.contacts.push({
        firstName: "",
        lastName: "",
        services: ko.observableArray([new Catalog(serviceTypes)])
    });
 };

 self.addService = function (contact) {
    contact.services.push(new Catalog(serviceTypes));
 };

Fiddle Demo 小提琴演示

You are binding all your services select elements to the same $root.selectedId value.That's why the corresponding subscribe is being fired upon any change in any of them. 您将所有services select元素都绑定到相同的$root.selectedId值,这就是为什么其中任何一个更改都会触发相应的subscribe的原因。

You need to bind the value dynamically based on the contact record for example. 例如,您需要根据contact记录动态绑定值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM