如果observableArray数组与Knockout JS没有匹配的索引,如何禁用

时间:2012-03-21 18:55:22

标签: javascript knockout.js

我有一个带有一个数组属性的简单模型对象。

示例:

{name: 'Foo', tags = ['fun', 'cool', 'geek']};

我在视图模型中向obervableArray添加了其中一个模型。

//pseudo code
oa.add({name: 'Foo', tags: ['fun', 'cool', 'geek']});
oa.add({name: 'Bar', tags: ['sad', 'dorky', 'uncool']});
oa.add({name: 'Qwerty', tags: ['keys', '101', 'geek']});

现在,当我根据标记过滤项目时,我想显示一条消息,表明没有更多具有特定标记的项目。

过滤代码:

// self = this;
self.filter = ko.observable('');
self.filterItems = ko.dependentObservable (function() {
    var filter = this.filter();
    if (!filter) {
        return this.items();
    } else {
        return ko.utils.arrayFilter(this.items(), function(item) {
                try {
                    if (compareAssociativeArrays(item.tags, filter)) {
                        return true;
                    }
                } catch (e) {}
                self.items.remove(item);
        });
    }
}, this);

是否可以使用indexOf标签值对给定长度的项进行数据绑定?

更新

我确实提出了一个解决方案,但不确定是否最好。有了它,我也可以修改和检索总数:

self.hasGeek = ko.computed(function () {
    var sum = 0;
    var item;
    for (var i=0; i<self.items().length; i++) {
        var item = self.items()[i];
        if (item.tags().indexOf('geek') != -1) {
            sum++;
        }
    }
    return (sum > 0) ? true : false;
});

2 个答案:

答案 0 :(得分:1)

我不确定您的确切结构,但我会设置一个计算的observable来表示您的过滤项目。然后,您可以包含一个部分,其可见性由计算出的可过滤的已过滤项目的长度控制。

就像:http://jsfiddle.net/rniemeyer/aVtpc/

Tag Filter: <input data-bind="value: tagFilter" />

<hr/>

<div data-bind="visible: !filteredItems().length">
    No items found
</div>

<ul data-bind="foreach: filteredItems">
    <li data-bind="text: name"></li>
</ul>​

JS:

var ViewModel = function() {
    this.tagFilter = ko.observable();
    this.items = ko.observableArray([
        {name: 'Foo', tags: ['fun', 'cool', 'geek']},
        {name: 'Bar', tags: ['sad', 'dorky', 'uncool']},
        {name: 'Qwerty', tags: ['keys', '101']}
    ]);

    this.filteredItems = ko.computed(function() {
        var filter = this.tagFilter();

        if (!filter) {
           return this.items();   
        }

        return ko.utils.arrayFilter(this.items(), function(item) {       
            return ko.utils.arrayFirst(item.tags, function(tag) {
                  return tag === filter;         
            });                
        });
    }, this);
};

ko.applyBindings(new ViewModel());

答案 1 :(得分:0)

我的头部快速伪代码...在你过滤oa后,也许使用计算函数,你可以这样做:

<span data-bind="text: filterOa().length"></span>
<!-- ko: foreach filterOa -->
   <span data-bind="text: name"></span>
<!-- /ko -->
<!-- if: filterOa().length === 0 -->
    You got nothing
<!-- /ko -->