Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
137 views
in Technique[技术] by (71.8m points)

javascript - How to use knockout to iterate over an object (not array)

I want to use something similar to the Knockout foreach construct to iterate over the properties of an object. Here is what I am trying to create...

DESIRED RESULT

<table>
    <tr>
        <td>Name 1</td>
        <td>8/5/2012</td>
    </tr>
    <tr>
        <td>Name 2</td>
        <td>2/8/2013</td>
    </tr>
</table>

However, my model looks like this...

JS

function DataModel(){
    this.data = ko.observableArray([{
                        entityId: 1,
                        props: {
                            name: 'Name 1',
                            lastLogin: '8/5/2012'
                        }
                    },
                    {
                        entityId: 2,
                        props: {
                            name: 'Name 2',
                            lastLogin: '2/8/2013'
                        }
                    }]);
}

var dataModel = new DataModel();
ko.applyBindings(dataModel);

Each row has an entityId and props which is an object itself. This template doesn't work, but how would I change it to generate the desired table above?

EDIT: The props in this example are name and lastLogin, but I need a solution that is agnostic to what is contained inside props.

I have this FIDDLE going as well.

HTML

<div data-bind="template: { name: 'template', data: $data }"></div>

<script type="text/html" id="template">
    <table>
        <tr data-bind="foreach: data()">
            <td data-bind="text: entityId"></td>  
        </tr>
    </table> 
</script>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

In a modern browser (or with an appropriate polyfill) you can iterate over Object.keys(obj) (the method returns only own enumerable properties, meaning that there is no need for an additional hasOwnProperty check):

<table>
  <tbody data-bind="foreach: {data: data, as: '_data'}">
    <tr data-bind="foreach: {data: Object.keys(props), as: '_propkey'}">
      <th data-bind="text: _propkey"></th>
      <td data-bind="text: _data.props[_propkey]"></td>
    </tr>
  </tbody>
</table>

Fiddled.

NB: I was simply curious to see if this would work, the template body above is more polluted than what I'd like to use in production (or come back to a few months later and be like "wtf").

Custom binding would be a better option, my personal preference though would be to use a computed observable or a writeable computed observable (the latter would be handy when working with json responses a-la restful api).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...