44

Knockout foreach コンストラクトに似たものを使用して、オブジェクトのプロパティを反復処理したいと考えています。これが私が作成しようとしているものです...

望ましい結果

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

しかし、私のモデルはこのように見えます...

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);

各行には、オブジェクト自体である entityId と props があります。このテンプレートは機能しませんが、上記の目的のテーブルを生成するにはどうすれば変更できますか?

編集:propsこの例の はnamelastLoginですが、 の内容にとらわれない解決策が必要ですprops

私はこのフィドルも行っています。

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>
4

8 に答える 8

66

最新のブラウザー (または適切なポリフィルを使用) では、反復処理を行うことができますObject.keys(obj)(メソッドは独自の列挙可能なプロパティのみを返すため、追加のチェックは必要ありませんhasOwnProperty)。

<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>

いじられた。

注意:これが機能するかどうかを知りたかっただけです。上記のテンプレートの本文は、本番環境で使用したいものよりも汚染されています (または、数か月後に戻って「wtf」のようになります)。

カスタムバインディングはより良いオプションですが、私の個人的な好みは、計算されたオブザーバブルまたは書き込み可能な計算されたオブザーバブルを使用することです(後者は、jsonレスフルAPIの応答を操作するときに便利です)。

于 2013-11-18T03:34:47.093 に答える
46

変換を処理するバインディング ハンドラーをいつでも作成できます。

ko.bindingHandlers.foreachprop = {
  transformObject: function (obj) {
    var properties = [];
    ko.utils.objectForEach(obj, function (key, value) {
      properties.push({ key: key, value: value });
    });
    return properties;
  },
  init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
    var properties = ko.pureComputed(function () {
      var obj = ko.utils.unwrapObservable(valueAccessor());
      return ko.bindingHandlers.foreachprop.transformObject(obj);
    });
    ko.applyBindingsToNode(element, { foreach: properties }, bindingContext);
    return { controlsDescendantBindings: true };
  }
};

次に適用します。

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

<script type="text/html" id="template">
    <table>
        <tbody data-bind="foreach: data">
            <tr data-bind="foreachprop: props">
                <td data-bind="text: value"></td>
            </tr>
        </tbody>
    </table> 
</script>
于 2013-02-12T22:22:17.430 に答える
3
<table>
    <tr data-bind="foreach: {data: data, as: 'item'}">
        <td data-bind="foreach: { data: Object.keys(item), as: 'key' }">
            <b data-bind="text: item[key]"></b>
        </td>  
    </tr>
</table>

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);

参考になれば幸いです(簡潔で申し訳ありません)

付録:

これは、テストされている実際の例です...

<table class="table table-hover">
    <thead>
        <tr>
            <!-- ko foreach: gridOptions.columnDefs -->
            <th data-bind="text: displayName"></th>
            <!-- /ko -->
        </tr>
    </thead>
    <tbody>
        <!-- ko foreach: {data: gridOptions.data, as: 'item'} -->
        <tr>
            <!-- ko foreach: {data: Object.keys(item), as: 'key'} -->
            <td>
                <span data-bind="text: item[key]"></span>
            </td>
            <!-- /ko -->
        </tr>
        <!-- /ko -->
    </tbody>
</table>
于 2014-05-30T18:10:28.060 に答える