javascript - 将 View 模型绑定(bind)到 knockout 中属性的存在

标签 javascript html knockout.js html-tag-details html-tag-summary

我正在使用 Knockout.js 填充一组 HTML5 <details>元素。这是结构:

<div class="items" data-bind="foreach: Playlists">
    <details class="playlist-details" data-bind="attr: {id: 'playlist-details-' + $index()}">
        <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"
        },
        {
            name: "My Playlist2",
            count: 5,
            items: [<LIST OF SONG ID'S>],
            playbtn_title: "Play this playlist"
        },
        {
            name: "My Playlist3",
            count: 0,
            items: [],
            playbtn_title: "You need to add items to this list before you can play it!"
        }
    ]
};

我想添加记住 open or closed state 的能力的详细信息 View 。我之前使用 jQuery 实现了此行为和 localStorage 1,但对于这个项目,我想原生使用 Knockout 而不是使用 jQuery。

我添加了一个 isOpenlocalStorage 检索到的 ViewModel 中播放列表的属性页面加载时。但是,我似乎无法使用 attr在 Knockout 中绑定(bind),因为 HTML5 spec说只寻找 presence or absenceopen属性,而不是值。

如何让 Knockout 添加和删除 open <details> 的属性(property)元素为 isOpen ViewModel 的属性改变了吗?


1:像这样:

// On the initial page load.
contents += '<details ' + ((localStorage['tl_open_playlist-details-' + counter] == 1) ? 'open' : '') ' class="playlist-details" id="playlist-details-' + counter + '" data-name="' + escape(listname) + '">'

...

// Update storage when things are clicked.
$(document).on('DOMSubtreeModified', 'details.playlist-details', function() {
    if ($(this).prop('open')) {
        localStorage['tl_open_' + this.id] = 1;
    } else {
        delete localStorage['tl_open_' + this.id];
    }
});

最佳答案

您可以修改 attr 绑定(bind)以考虑另一个绑定(bind)选项(此处名为 attrRemoveWhenFalse)并为您删除该属性:

<input class='testInput' type="text" 
       data-bind="attr: { disabled: isDisabled }, attrRemoveWhenFalse: true" />

var originalAttr = { init: ko.bindingHandlers.attr.init, 
                     update: ko.bindingHandlers.attr.update }
ko.bindingHandlers.attr.update = function (element, valueAccessor, 
                                           allBindingAccessor, viewModel, 
                                           bindingContext) {
    if (typeof originalAttr.update === 'function') 
        originalAttr.update(element, valueAccessor, allBindingAccessor, 
                            viewModel, bindingContext);
    if (allBindingAccessor().attrRemoveWhenFalse) {
        for (var prop in valueAccessor()) {
            if (!ko.utils.unwrapObservable(valueAccessor()[prop])) {
                element.removeAttribute(prop);
            }
        }
    }
}

Demo

关于javascript - 将 View 模型绑定(bind)到 knockout 中属性的存在,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24785460/

相关文章:

javascript - OpenLayers 重绘不起作用

javascript - CSS3 transform rotate using mouse position - 第二阶段

javascript - 关于 Knockout JS 的澄清

knockout.js - knockout 验证 ko.validation.group 与 ko.validatedObservable

javascript - D3 : Separating data exit/remove/merge from drawing of elements

javascript - 纯 Javascript - setInterval (1s), setAttribute

html - 当我转到询问页面时,页脚不会粘在底部

javascript - 如何定义使用先前值确定 Knockout 类的自定义绑定(bind)?

javascript - 如何将值传递给函数并继续执行

html - 尝试用 div 替换表格但部分成功