Knockout.js を使用して、一連の HTML5<details>
要素を設定しています。構造は次のとおりです。
<div class="items" data-bind="foreach: Playlists">
<details class="playlist-details" data-bind="attr: {id: 'playlist-details-' + $index(), open: isOpen}">
<summary>
<span data-bind="text: name"></span> - <span data-bind="text: count"></span> item(s)
<div class="pull-right">
<button data-bind="click: $parent.play, css: {disabled: count() == 0}, attr: {title: playbtn_title}" class="btn"><i class="icon-play"></i> Play</button>
<button data-bind="click: $parent.deleteList" class="btn btn-danger"><i class="icon-trash"></i> Delete</button>
</div>
</summary>
<div class="list" data-bind="with: items" style="padding-top: 2px;">
...
</div>
</details>
</div>
ViewModel のデータは次のようになります。
var VM = {
Playlists: [
{
name: "My Playlist1",
count: 3,
items: [<LIST OF SONG ID'S>],
playbtn_title: "Play this playlist",
isOpen: true
},
{
name: "My Playlist2",
count: 5,
items: [<LIST OF SONG ID'S>],
playbtn_title: "Play this playlist",
isOpen: null
},
{
name: "My Playlist3",
count: 0,
items: [],
playbtn_title: "You need to add items to this list before you can play it!",
isOpen: null
}
]
};
ViewModel のプロパティとバインディングを使用して、詳細ビューの開いている状態または閉じている状態を記憶する機能を追加しました(最初に説明したように ここ)。isOpen
attr
ただし、クリックし<summary>
て詳細を展開しても、ViewModel は更新されません。バインディングとは異なりvalue
、attr
バインディングは双方向ではありません。
属性値が変更されたときにこのバインディングを更新するにはどうすればよいですか?
要素が開いたり閉じたりしたときにブラウザがイベントをトリガーすることは知っていますが、DOMSubtreeModified
そこに何を入れるかはわかりません-私が試したいくつかのこと(、、などを含む.notifySubscribers()
)if (list.open()) ...
がループを引き起こし、プロパティが変更されるとイベント トリガーが再び発生すると、プロパティが再び変更され、イベントが再びトリガーされます。