Knockout修改嵌套对象的一部分

时间:2014-03-10 14:49:52

标签: knockout.js knockout-mapping-plugin

我是淘汰赛的新手,我正在努力解决如何更新视图模型的一部分问题。我有一个WCF api,它返回一个包含公司名称和分区列表的JSON字符串。在每个部门中,它可以包含多个地址和联系人。每个联系人也可以有多个地址。我正在使用ko.mapping将数据映射到我的视图模型,据我所知,它为所有属性创建了observable。我可以使用嵌套的foreach循环正确显示数据,如下面的链接/代码所示。

我的问题是点击了编辑链接。我正在使用ko.dataFor(this),这将返回我的整个视图模型。我如何获得点击的具体地址或联系方式?

http://jsfiddle.net/T8P5Y/6/

的Javascript

$(function () {
    $("#addressDialog").hide();
    $("#contactDialog").hide();

    var data = {
        "CompanyID": 3,
            "CompanyName": "Company #1",
            "CompanyDivisions": [{
            "Addresses": [{
                "Address1": "1234 Broadway",
                    "Address2": null,
                    "AddressID": 51135,
                    "AddressType": {
                    "AddressTypeID": 1,
                        "Description": "Mailing"
                },
                    "City": "My City",
                    "ContactID": 0,
                    "Owner": null,
                    "State": {
                    "StateCode": "IL",
                        "StateID": 1,
                        "StateName": "Illinois"
                },
                    "Zip": "61234",
                    "ZipPlus4": "1111"
            }],
                "Contacts": [{
                "Addresses": [],
                    "ContactID": 8,
                    "ContactType": {
                    "ContactTypeID": 5,
                        "Description": "Supervisor"
                },
                    "CompanyID": 3,
                    "FirstName": "John",
                    "LastName": "Doe",
                    "MiddleName": ""
            }],
                "Division": {
                "Description": "Customer Service",
                    "DivisionCode": "CS",
                    "DivisionID": 1
            },
                "XrefID": 87173
        }, {
            "Addresses": [{
                "Address1": "1234 Broadway",
                    "Address2": "Dock #2",
                    "AddressID": 51134,
                    "AddressType": {
                    "AddressTypeID": 2,
                        "Description": "Delivery"
                },
                    "City": "My City",
                    "ContactID": 0,
                    "CompanyID": 3,
                    "State": {
                    "StateCode": "IL",
                        "StateID": 1,
                        "StateName": "Illinois"
                },
                    "Zip": "61234",
                    "ZipPlus4": "3050"
            }],
                "Contacts": [{
                "Addresses": [],
                    "ContactID": 9,
                    "ContactType": {
                    "ContactTypeID": 9,
                        "Description": "Executive Director"
                },
                    "CompanyID": 3,
                    "FirstName": "Jane",
                    "LastName": "Doe",
                    "MiddleName": ""
            }, {
                "Addresses": [],
                    "ContactID": 16,
                    "ContactType": {
                    "ContactTypeID": 13,
                        "Description": "Book Keeper"
                },
                    "CompanyID": 3,
                    "FirstName": "Tony",
                    "LastName": "Adams",
                    "MiddleName": null
            }, {
                "Addresses": [{
                    "Address1": "1234 Broadway",
                        "Address2": null,
                        "AddressID": 51950,
                        "AddressType": {
                        "AddressTypeID": 2,
                            "Description": "Delivery"
                    },
                        "City": "My City",
                        "ContactID": 17,
                        "CompanyID": 3,
                        "State": {
                        "StateCode": "IL",
                            "StateID": 1,
                            "StateName": "Illinois"
                    },
                        "Zip": "61234",
                        "ZipPlus4": null
                }],
                    "ContactID": 17,
                    "ContactType": {
                    "ContactTypeID": 10,
                        "Description": "CFO"
                },
                    "CompanyID": 3,
                    "FirstName": "Milton",
                    "LastName": "Freemon",
                    "MiddleName": null
            }],
                "Division": {
                "Description": "Accouting",
                    "DivisionCode": "AC",
                    "DivisionID": 4
            },
                "XrefID": 128438
        }, {
            "Addresses": [{
                "Address1": "1234 Broadway",
                    "Address2": null,
                    "AddressID": 51133,
                    "AddressType": {
                    "AddressTypeID": 2,
                        "Description": "Delivery"
                },
                    "City": "My City",
                    "State": {
                    "StateCode": "IL",
                        "StateID": 1,
                        "StateName": "Illinois"
                },
                    "Zip": "61234",
                    "ZipPlus4": "3050"
            }],
                "Contacts": [{
                "Addresses": [],
                    "ContactID": 10,
                    "ContactType": {
                    "ContactTypeID": 13,
                        "Description": "Programmer"
                },
                    "FirstName": "Jill",
                    "LastName": "Doe",
                    "MiddleName": null
            }, {
                "Addresses": [],
                    "ContactID": 13,
                    "ContactType": {
                    "ContactTypeID": 7,
                        "Description": "Network Engineer"
                },
                    "FirstName": "Matt",
                    "LastName": "Williams",
                    "MiddleName": null
            }],
                "Division": {
                "Description": "Information Technology",
                    "DivisionCode": "IT",
                    "DivisionID": 2
            },
                "XrefID": 133320
        }]
    };

    var viewModel = {
        company: ko.mapping.fromJS(data),
        selectedAddress: ko.observable(),
        selectedContact: ko.observable(),

        selectAddress: function () {
            viewModel.selectedAddress(this);
        },

        selectContact: function () {
            viewModel.selectedContact(this);
        },

    }

    ko.applyBindings(viewModel);
    createTabs();

    $(".address-edit").on("click", function () {
        viewModel.selectAddress(ko.dataFor(this));
        $("#addressDialog").dialog({
            buttons: {
                Save: function () {
                    $(this).dialog("close");
                },
                Cancel: function () {
                    $(this).dialog("close");
                }
            }
        });
    });

    $(".contact-edit").on("click", function () {
        viewModel.selectContact(ko.dataFor(this));
        $("#contactDialog").dialog({
            buttons: {
                Save: function () {
                    $(this).dialog("close");
                },
                Cancel: function () {
                    $(this).dialog("close");
                }
            }
        });
    });
});

function createTabs() {
    $("#tabs").tabs();
};

HTML

<div id="tabs" class="ui-tabs">
    <div data-bind="with: company">
         <h1 data-bind="text: CompanyName"></h1>

        <ul data-bind="foreach: CompanyDivisions">
            <li> <a data-bind="attr: { href: '#' + Division.DivisionCode(), title: Division.DivisionCode}, text: Division.DivisionCode">
                        <span data-bind="text: Division.DivisionCode"></span></a>

            </li>
        </ul>
        <div data-bind="foreach: CompanyDivisions">
            <div data-bind="attr: {id: Division.DivisionCode()}">
                 <h2 data-bind="text: Division.Description"></h2> 
                 <h3>Addresses</h3>

                <div data-bind="foreach: Addresses">
                    <div class="ui-widget ui-widget-content ui-corner-all box"> <b><span data-bind="text: AddressType.Description"></span></b>
 <a href="#" class="address-edit">Edit</a>| <a href="#" class="address-delete">Delete</a>

                        <br /> <span data-bind="text: Address1"></span>

                        <br /> <span data-bind="text: City"></span>, <span data-bind="text: State.StateCode"></span>
 <span data-bind="text: Zip"></span>- <span data-bind="text: ZipPlus4"></span>

                    </div>
                </div>
                <br />
                <div style="clear:both"></div>
                 <h3>Contacts</h3>

                <div data-bind="foreach: Contacts">
                    <div class="ui-widget ui-widget-content ui-corner-all box"> <b><span data-bind="text: ContactType.Description"></span></b>
 <a href="#" class="contact-edit">Edit</a>| <a href="#" class="contact-delete">Delete</a>

                        <br /> <span data-bind="text: LastName"></span>, <span data-bind="text: FirstName"></span>
 <span data-bind="text: MiddleName"></span>

                        <br />
                        <div data-bind="foreach: Addresses">
                            <br /> <b><span data-bind="text: AddressType.Description"></span></b>

                            <br /> <span data-bind="text: Address1"></span>

                            <br /> <span data-bind="text: City"></span>, <span data-bind="text: State.StateCode"></span>
 <span data-bind="text: Zip"></span>- <span data-bind="text: ZipPlus4"></span>

                        </div>
                    </div>
                </div>
                <div style="clear:both"></div>
            </div>
        </div>
    </div>
</div>
<div id="addressDialog" data-bind="with: selectedAddress">Address :
    <input type="text" data-bind="value: Address1" />
    <br />City :
    <input type="text" data-bind="value: City" />
    <br />Zip :
    <input type="text" data-bind="value: Zip" />
    <br />
</div>
<div id="contactDialog" data-bind="with: selectedContact">First :
    <input type="text" data-bind="value: FirstName" />
    <br />Middle :
    <input type="text" data-bind="value: MiddleName" />
    <br />Last :
    <input type="text" data-bind="value: LastName" />
    <br />
</div>

预先感谢您的协助,

格雷格

1 个答案:

答案 0 :(得分:0)

我已经更新了你的视图模型并删除了点击绑定上的jquery,而不是使用了敲击点击绑定。

var viewModel = {
    company: ko.mapping.fromJS(data),
    selectedAddress: ko.observable(),
    selectedContact: ko.observable(),

    selectAddress: function () {
        viewModel.selectedAddress(this);
    },

    selectContact: function () {
        viewModel.selectedContact(this);
    },
    edit: function (d) {
        viewModel.selectedAddress(d);
        $("#addressDialog").dialog({
            buttons: {
                Save: function () {
                    $(this).dialog("close");
                },
                Cancel: function () {
                    $(this).dialog("close");
                }
            }
        });
    },
    contactedit: function (d) {
        viewModel.selectedContact(d);
        $("#contactDialog").dialog({
            buttons: {
                Save: function () {
                    $(this).dialog("close");
                },
                Cancel: function () {
                    $(this).dialog("close");
                }
            }
        });
    }

}

ko.applyBindings(viewModel);

HTML

 <a href="#" data-bind="click: $root.edit" class="address-edit">Edit</a>
 <a href="#" data-bind="click: $root.contactedit" class="contact-edit">Edit</a>

Fiddle Demo