简体   繁体   中英

KnockoutJS binding to Key/Value pair

I am trying to bind to key/value pair data with KnockoutJS:

this.personal = {
  "name" : "Chuck",
  "country" : "USA"
};

In my HTML i use the $data binding:

<ul data-bind="foreach: personal">

  <li data-bind="text: $data"></li>

</ul>

which results in:

[object Object]

[object Object]

Does anybody know how my binding should look like if I want to see this:

name: Chuck

country: USA

in other words...how I can show the property name and the property value?

EDIT: Someone pointed me at: https://github.com/jamesfoster/knockout.observableDictionary But I still hope to bind without an extra library

There is an easier way of binding to a key-value pair using Knockout.js. Say you have a key value pair that looks like the following

myItems: [
            { Name: 'Item 1', Value: 1},
            { Name: 'Item 3', Value: 3},
            { Name: 'Item 4', Value: 4}
        ],

Just use the following html to bind to the key value pair.

<select data-bind="options: myItems, optionsText: 'Name', optionsValue: 'Value'></select>

References:

http://knockoutjs.com/documentation/options-binding.html

Try something like this:

<ul data-bind="keyvalue: properties">
    <li>
        <span data-bind="text: key"></span> :
        <span data-bind="text: value"></span>
    </li>
</ul>

For JavaScript:

function AppViewModel() {
    this.properties = { b: 'c', d: 'e' };
}

ko.bindingHandlers['keyvalue'] = {
    makeTemplateValueAccessor: function(valueAccessor) {
        return function() {
            var values = valueAccessor();
            var array = [];
            for (var key in values)
                array.push({key: key, value: values[key]});
            return array;
        };
    },
    'init': function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        return ko.bindingHandlers['foreach']['init'](element, ko.bindingHandlers['keyvalue'].makeTemplateValueAccessor(valueAccessor));
    },
    'update': function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        return ko.bindingHandlers['foreach']['update'](element, ko.bindingHandlers['keyvalue'].makeTemplateValueAccessor(valueAccessor), allBindings, viewModel, bindingContext);
    }
};

ko.applyBindings(new AppViewModel());

Create a function in your view model that converts the object property names and values into an array of objects with key and value properties containing the aforementioned name and value.

var ExampleViewModel = function () {
    var self = this;

    self.personal = {
        "name": "Loek",
        "country": "Netherlands"
    };

    self.personalList = function () {
        var list = [];

        for (var i in self.personal) if (self.personal.hasOwnProperty(i)) {
            list.push({
                "key": i,
                "value": self.personal[i]
            });
        }

        return list;
    };
};

Your html template should look like the following:

<ul data-bind="foreach: personalList()">
    <li data-bind="text: $data.key + ': ' + $data.value"></li>
</ul>

This results in the following output:

  • name: Loek
  • country: Netherlands

Here's a fiddle with a working example.

I think you should do

<ul data-bind="foreach: personal">
  <li data-bind=" text: country"></li>
  <li data-bind=" text: name"></li>
</ul>​

// This is a simple *viewmodel* - JavaScript that defines the data and behavior of your UI
function AppViewModel() {
    // Use an array here
    this.personal = [{
        "name": "Loek",
        "country": "Netherlands"
    }];
}

// Activates knockout.js
ko.applyBindings(new AppViewModel());​

fiddle http://jsfiddle.net/Aw5hx/

PS i never used knockoutJS before this post so i'm no world expert.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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