将 select 列表添加到不填充 selects 值的淘汰 VM

Adding a select list to knockout VM not populating selects value

我正在尝试学习一些 knockout.js 所以我 运行 通过网站上的示例,特别是联系示例。 (Knockout Contacts Editor)

我正在尝试通过添加 select 列表来扩展此示例,其中 属性 为 'ContactType'

ContactType 是包含 2 个对象的基本列表。

我创建了一个示例的分支并稍微扩展了它 My Extended Example fiddle

  var initialData = {
    "names": [{
        firstName: "Danny",
        lastName: "LaRusso",
        contactTypeId: 1,
        phones: [{
            type: "Mobile",
            number: "(555) 121-2121"
        }, {
            type: "Home",
            number: "(555) 123-4567"
        }]
    }, {
        firstName: "Sensei",
        lastName: "Miyagi",
        contactTypeId: 2,
        phones: [{
            type: "Mobile",
            number: "(555) 444-2222"
        }, {
            type: "Home",
            number: "(555) 999-1212"
        }]
    }],
        "contactTypes": [{
        "id": 1,
            "type": "Family"
    }, {
        "id": 2,
            "type": "Friend"
    }]
}

var ContactsModel = function (contacts) {
    var self = this;

    self.contactTypes = ko.observableArray(ko.utils.arrayMap(contacts.contactTypes,

    function (contactType) {
        return {
            id: contactType.id,
            type: contactType.type
        };
    }));


    self.contacts = ko.observableArray(ko.utils.arrayMap(contacts.names, function (contact) {
        return {
            firstName: contact.firstName,
            lastName: contact.lastName,
            phones: ko.observableArray(contact.phones),
            contactTypeId: ko.observable(contact.contactTypeId)
        };
    }));

    self.addContact = function () {
        self.contacts.push({
            firstName: "",
            lastName: "",
            phones: ko.observableArray(),
            contactTypeId: ko.observable()
        });
    };

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

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

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

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

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

ko.applyBindings(new ContactsModel(initialData));

HTML

<div class='liveExample'>
     <h2>Contacts</h2>

    <div id='contactsList'>
        <table class='contactsEditor'>
            <tr>
                <th>First name</th>
                <th>Last name</th>
                <th>Contact Type</th>
                <th>Phone numbers</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>
                        <select class="form-control" data-bind="options: $root.contactTypes,
                                    optionsText: 'type',
                                    optionsValue:'id',
                                     value:'contactTypeId',
                                    optionsCaption: 'Please Select...'"></select>
                    </td>
                    <td>
                        <table>
                            <tbody data-bind="foreach: phones">
                                <tr>
                                    <td>
                                        <input data-bind='value: type' />
                                    </td>
                                    <td>
                                        <input data-bind='value: number' />
                                    </td>
                                    <td><a href='#' data-bind='click: $root.removePhone'>Delete</a>

                                    </td>
                                </tr>
                            </tbody>
                        </table> <a href='#' data-bind='click: $root.addPhone'>Add number</a>

                    </td>
                </tr>
            </tbody>
        </table>
    </div>
    <p>
        <button data-bind='click: addContact'>Add a contact</button>
        <button data-bind='click: save, enable: contacts().length > 0'>Save to JSON</button>
    </p>
    <textarea data-bind='value: lastSavedJson' rows='5' cols='60' disabled='disabled'></textarea>
</div>

我有 2 个问题,我不确定自己做错了什么。

加载页面时,select 列表未显示正确的值。相反,它只显示 'Please Select' 值

当我尝试保存记录时,未保存 select 列表中的 selected 值。

我在这里做错了什么吗?

问题是您未正确设置 value 绑定。而不是 value: 'contactTypeId' 而应该是 value: contactTypeId 而不是引号。

<select class="form-control" data-bind="options: $root.contactTypes,
    optionsText: 'type',
    optionsValue: 'id',
    value: contactTypeId,                                    
    optionsCaption: 'Please Select...'">
</select>

另外,对于保存功能,最好使用敲除 ko.toJSON 而不是 JSON.stringify(ko.toJS

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