KnockOut.JS使用来自observable的值填充下拉列表

时间:2013-10-01 15:25:05

标签: javascript html data-binding knockout.js

我有使用knockout的视图和绑定,我试图使用我的observable数组中的值填充我的下拉菜单,但我的html以某种方式覆盖它并显示默认字符串。

我的HTML

  <table id="tblBrands">
        <tr data-bind="foreach: agency">

            <td>
                <table>
                    <tr>
                        <td>Advertiser Name
                        </td>
                        <td>Account Name
                        </td>
                        <td>Responsibility
                        </td>
                        <td>Full Name
                        </td>
                    </tr>
                    <tbody data-bind="foreach: brands">
                        <tr>
                            <td>
                                <input data-bind="value: advertiserName" /></td>

                            <td>
                                <input data-bind="value: brandName" /></td>

                            <td>
                               <!-- <select data-bind="value: responsibility" />-->



                                <select data-bind="value: responsibility">
                                    <option value="">Select...</option>
                                    <option value="">Media Manager</option>
                                    <option value="">Strategic Responsibility</option>
                                    <option value="">Planning/Buying</option>
                                </select>

                            </td>

                            <td>
                                <input data-bind="value: fullName" /></td>

                            <td><a href='#' data-bind='click: $root.removeBrand' style="color: blue">Remove</a></td>
                        </tr>
                    </tbody>
                </table>
            </td>

        </tr>
    </table>

我正在尝试将其绑定到下拉菜单:

<select data-bind="value: responsibility">

代理商JS

我的代理商视图模型非常大,但这就是它的工作原理:

define(['services/datacontext'], function (dataContext) {
    var initialized = false;
    var agency;


    agency = ko.observableArray([]);

    var save = function () {
        // Clear Cache because user submitted the form. We don't have to hold onto data anymore.
        localStorage.setItem('Agency', null);
        localStorage.setItem('Offices', null);
        localStorage.setItem('Brands', null);

        var agency = ko.toJS(vm.agency._latestValue[0]) //Drill down to _latestValue and convert this to standard JS object

        var s = YUI().use("json-stringify", function (Y) {
            var jsonAgency = Y.JSON.stringify(agency, [
                "activities",
                "agencyName",
                "agencyID",
                "category",
                "declaredBillings",
                "immediateParent",
                "numberOfEmployees",
                "ultimateParent",
                "uRL",
                "offices",
                "address1",
                "address2",
                "address3",
                "address4",
                "address5",
                "agencyID",
                "faxNumber",
                "officeID",
                "postCode",
                "telephoneNumber",
                "contacts",
                "emailAddress",
                "firstName",
                "jobName",
                "personID",
                "surName",
                "title",
                "brands",
                "agencyId",
                "brandId",
                "brandName",
                "categoryDescription",
                "dateAmended",
                "activities",
                "additionalInfo",
                "advertiserId",
                "advertiserName",
                "alfRank",
                "cinemaRank",
                "directMailRank",
                "internetRank",
                "nielsenId",
                "notes",
                "numberOfEmployees",
                "outdoorRank",
                "pressRank",
                "radioRank",
                "tVRank"
            ]);
            dataContext.saveChanges(jsonAgency, localStorage.setItem('AgencyCurrent', jsonAgency)); // Pass current data from cache and new data from form

        })
    }

    var vm = { // This is my view model, my functions are bound to it. 
        //These are wired up to my agency view
        activate: activate,
        agency: agency,
        title: 'agency',
        refresh: refresh, // call refresh function which calls get Agencies
        save: save,
        cacheForm: cacheForm,
        addOffice: addOffice,
        removeOffice: removeOffice,
        addBrand: addBrand,
        removeBrand: removeBrand,
        addContact: addContact,
        removeContact: removeContact
    };
    return vm;

    function activate() {
        vm.agency;
        if (initialized) {
            return;
        }
        initialized = false;
        refresh();
    }

    function refresh() {
        dataContext.getAgency(agency);
    }


    function cacheForm(agency) {

        var agency = ko.toJS(vm.agency._latestValue[0]) //Drill down to _latestValue and convert this to standard JS object

        //Check if the current data has been cached before caching the new data, otherwise just cache the new data.
        if (!localStorage.AgencyCurrent) {
            var s = YUI().use("json-stringify", function (Y) {
                var jsonAgency = Y.JSON.stringify(agency, [
                    "activities",
                    "agencyName",
                    "agencyID",
                    "campaignBillings",
                    "category",
                    "declaredBillings",
                    "immediateParent",
                    "numberOfEmployees",
                    "ultimateParent",
                    "uRL",
                    "offices",
                    "address1",
                    "address2",
                    "address3",
                    "address4",
                    "address5",
                    "agencyID",
                    "faxNumber",
                    "officeID",
                    "postCode",
                    "telephoneNumber",
                    "contacts",
                    "emailAddress",
                    "firstName",
                    "jobName",
                    "personID",
                    "surName",
                    "title",
                    "brands",
                    "agencyId",
                    "brandId",
                    "brandName",
                    "categoryDescription",
                    "dateAmended",
                    "activities",
                    "additionalInfo",
                    "advertiserId",
                    "advertiserName",
                    "alfRank",
                    "cinemaRank",
                    "directMailRank",
                    "internetRank",
                    "nielsenId",
                    "notes",
                    "numberOfEmployees",
                    "outdoorRank",
                    "pressRank",
                    "radioRank",
                    "tVRank"
                ]);
                localStorage.setItem('AgencyCurrent', null);
                localStorage.setItem('AgencyCurrent', jsonAgency);
            }) 
        }

        var brands = ko.toJS(vm.brands);

        var s = YUI().use("json-stringify", function (Y) {
            var jsonStrAgency = Y.JSON.stringify(agency, [
                "activities",
                "agencyName",
                "agencyID",
                "campaignBillings",
                "category",
                "declaredBillings",
                "immediateParent",
                "numberOfEmployees",
                "ultimateParent",
                "uRL"
            ]); // Use an array of acceptable object key names as a whitelist.
            var jsonStrOfficesContacts, jsonStrBrandsAdvertisers;

            for (i in agency.offices) { // Outer loop for each office
                jsonStrOfficesContacts = Y.JSON.stringify(agency.offices, [
                    "address1",
                    "address2",
                    "address3",
                    "address4",
                    "address5",
                    "agencyID",
                    "faxNumber",
                    "officeID",
                    "postCode",
                    "telephoneNumber",
                    "contacts", // From this point on I am drilling into office[n].contacts data
                    "emailAddress",
                    "firstName",
                    "jobName",
                    "personID",
                    "surName",
                    "title"
                ]);
            }
            jsonStrBrandsAdvertisers = Y.JSON.stringify(brands, [
                "agencyId",
                "brandId",
                "brandName",
                "categoryDescription",
                "dateAmended",
                "defaultSearchName1",
                "defaultSearchName2",
                "advertiser", //brands.advertser
                "activities",
                "additionalInfo",
                "advertiserId",
                "advertiserName",
                "alfRank",
                "cinemaRank",
                "directMailRank",
                "internetRank",
                "nielsenId",
                "notes",
                "numberOfEmployees",
                "outdoorRank",
                "pressRank",
                "radioRank",
                "tVRank"
            ]);

            localStorage.setItem('Agency', null);
            localStorage.setItem('Offices', null);
            localStorage.setItem('Brands', null);

            localStorage.setItem('Agency', jsonStrAgency);
            localStorage.setItem('Offices', jsonStrOfficesContacts);
            localStorage.setItem('Brands', jsonStrBrandsAdvertisers);
        });
        //var objBrands = new Object(ko.mapping.fromJSON(localStorage.getItem('Brands')));

        //    for (i in objBrands._latestValue) {
        //        for (a in objBrands._latestValue[i]) {
        //            if (a == "advertiser") {
        //                objAdvertiser = objBrands._latestValue[i].advertiser; // get advertiser data
        //                objBrands.unshift(objBrands._latestValue[i].advertiser) // unshift it from root
        //                // create temp objects
        //                var tempBrands = ko.toJS(objBrands);
        //                var tempAdvertiser = ko.toJS(objAdvertiser);
        //                brands[i].advertiser = tempAdvertiser;

        //            }
        //        }
        //    }
    }

    function addOffice() {
        //Convert agency observable to object
        var objAgency = ko.toJS(vm.agency);

        var objOffice = {
            address1: " ",
            address2: " ",
            address3: " ",
            address4: " ",
            address5: " ",
            agencyID: " ",
            contacts: [],
            faxNumber: " ",
            officeID: " ",
            postCode: " ",
            telephoneNumber: " ",
        }

        objAgency[0].offices.unshift(objOffice); // Add new object to agency
        vm.agency([ko.mapping.fromJS(objAgency[0])]); //Bind back to KO
    }

    function removeOffice(office) {
        var ID = office.officeID._latestValue;
        agency._latestValue[0].offices.remove(office);
    }

    function addContact(office) { // Passing in object array of agency. We no it contains correct office and agency ID

        // Assign observable data to new variable then remove old
        // variable from mapping
        var objAgency = ko.toJS(agency);
        var officeTableNum;
        //vm.agency.removeAll();

        var agencyID = office.agencyID._latestValue;
        var officeID = office.officeID._latestValue


        // Fill new object with empty strings and related data
        var objContact = {
            agencyID: agencyID,
            emailAddress: "",
            firstName: "",
            jobName: "",
            office: "",
            OfficeID: officeID,
            personID: "",
            surName: "",
            title: "",
            responsibilities: "",
            notes: ""
        }    
        // Splice where office ID match
        for (i in objAgency[0].offices) {
            if (!isNaN(i)) {
                if (objAgency[0].offices[i].officeID === officeID) {
                    // set var for tracking office i.e. office 1, 2, 3
                    officeTableNum = i + 1; // Because of 0 index, add 1
                    objAgency[0].offices[i].contacts.unshift(objContact); // At i remove one object
                }
                else {
                }
            }
        }
        vm.agency([ko.mapping.fromJS(objAgency[0])]);
    }

    function removeContact(contact) {
        for (i in agency._latestValue[0].offices._latestValue) {
            if (isNaN(i)) { // Escape if NaN, otherwise use index valI ha

            }
            else {
                for (ii in agency._latestValue[0].offices._latestValue[i].contacts._latestValue) {
                    agency._latestValue[0].offices._latestValue[i].contacts.remove(contact);
                }
            }
        }
    }

    function addBrand() {

        //Convert agency observable to object
        var objAgency = ko.toJS(vm.agency);

        var objBrand = {
            brandName: " ",
            advertiserName: " ",
            aLFRank: " ",
            totalRank: " ",
            cinemaRank: " ",
            directMailRank: " ",
            internetRank: " ",
            outdoorRank: " ",
            pressRank: " ",
            radioRank: " ",
            tVRank: " ",
        }

        objAgency[0].brands.unshift(objBrand); // Add new object to agency
        vm.agency([ko.mapping.fromJS(objAgency[0])]); //Bind back to KO 
    }

    function removeBrand(brand) {
        var ID = brand.brandID._latestValue;
        agency._latestValue[0].brands.remove(brand);
    }
});

摘要

想要将我的可观察数组数据绑定到下拉菜单,同时也提供下拉项目。

修改

新VM

 var vm = { // This is my view model, my functions are bound to it. 
        //These are wired up to my agency view
        activate: activate,
        agency: agency,
        title: 'agency',
        refresh: refresh, // call refresh function which calls get Agencies
        save: save,
        cacheForm: cacheForm,
        addOffice: addOffice,
        removeOffice: removeOffice,
        addBrand: addBrand,
        removeBrand: removeBrand,
        addContact: addContact,
        removeContact: removeContact,
        responsibilityOptions: ['France', 'Germany', 'Spain']
    };
    return vm;

新约束

 <select data-bind="options: $root.responsibilityOptions, value: responsibility"></select>

Screenshot

2 个答案:

答案 0 :(得分:2)

您应该使用选项绑定选项。

文档位于:http://knockoutjs.com/documentation/options-binding.html

基本上你这样做:

<select data-bind="options: yourArray, value: responsibility"></select>

只需将yourArray替换为您想要填充下拉列表的内容。

因此,不要在HTML中添加选项,而是将它们放在observableArray中,并使用它代替yourArray

看看这个被打败的小提琴看看它是否会帮助你:http://jsfiddle.net/r3AA9/

答案 1 :(得分:0)

这就是我用ko

绑定我的下拉列表的方式
<select data-bind="options: ['DU','IDU','IDU/DU','Former IDU'], value: UserType" class="box-select" />