将视图模型绑定到剔除中属性的存在 [英] binding viewmodel to existence of a property in knockout

查看:84
本文介绍了将视图模型绑定到剔除中属性的存在的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am using Knockout.js to populate a set of HTML5 <details> elements. Here is the structure:

<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中的数据如下所示:

The data in the ViewModel looks something like this:

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!"
        }
    ]
};

我想添加一种功能来记住详细信息视图的打开或关闭状态.我以前使用jQuerylocalStorage 1 实现了此行为,但是对于这个项目,我想本地使用Knockout而不是jQuery.

I want to add the ability to remember the open or closed state of the details view. I have implemented this behavior previously using jQuery and localStorage1, but for this project I want to use Knockout natively instead of using jQuery.

我在ViewModel的播放列表中添加了一个isOpen属性,该属性在页面加载时从localStorage中检索.但是,似乎我无法在淘汰赛中使用attr绑定,因为

I have added an isOpen property to the playlists in the ViewModel which is retrieved from localStorage when the page loads. However, it seems that I can't use the attr binding in Knockout because the HTML5 spec says to look only for the presence or absence of the open attribute, not for a value.

当ViewModel的isOpen属性更改时,我如何让Knockout添加和删除<details>元素的open属性?

How would I get Knockout to add and remove the open property of the <details> element as the isOpen property of the ViewModel changes?

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绑定,以考虑另一个绑定选项(此处命名为attrRemoveWhenFalse)并为您删除属性:

You can modify the attr binding to take into account another binding option (named attrRemoveWhenFalse here) and remove the attribute for you:

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

这篇关于将视图模型绑定到剔除中属性的存在的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆