【问题标题】:How to filter observable array and return the same如何过滤可观察数组并返回相同的
【发布时间】:2013-08-09 22:29:37
【问题描述】:

我有可观察的数组。我想根据一些文本过滤可观察的。我将选择选项按钮,根据它我需要过滤可观察数组并绑定到表。到目前为止,这是我的代码。 这是我的看法

<table>
<tbody data-bind="foreach: dataOne">
    <tr   >
        <td data-bind="text: id"></td><td >&nbsp;&nbsp;&nbsp;</td>
        <td data-bind="text: display"></td><td >&nbsp;&nbsp;&nbsp;</td>
        <td>&nbsp;</td>

    </tr>
</tbody>

<table >
       <tr>
            <td><input name="optbtn" type="radio" value="All"/> All</td>
            <td><input name="optbtn" type="radio" value="Selected"/> Selected</td>
        </tr>

</table>

这是我的视图模型

 var data1 = [{
  name1: "one",
  id: 1,
display: "<temp>Is this employee</temp> required <val>in our company</val>"
}, {
name1: "two",
id: 2,
 display: "<temp>Is this bachelor</temp>required in our group"
}, {
name1: "three",
id: 3,
 display: "Test"

}];


var viewModel = {
dataOne: ko.observableArray(data1),

};


$("input[name='optbtn']").change(function (e) {
        debugger;
        var str = "<temp>";
        var stringFromArray = "";
        if ($(this).val() == "All") {
            alert("All");
        }
        else {
            ko.utils.arrayFirst(self.dataOne(), function (data) {
                debugger;
                stringFromArray = data.display();
                if (stringFromArray.indexOf(str) == 0) {
                    return data.display();
                }

            });
        }
    });


ko.applyBindings(viewModel);

如果我选择“已选择”选项按钮,那么它应该只返回文本 "&lt;temp&gt;in 。 所以它应该只返回 2 条记录。

我怎样才能做到这一点?当我加载我的页面时,它将显示所有记录并将“全部”按钮标记为选中。当我选择“已选择”时,它必须过滤记录。

更新

这是我的Fiddle

【问题讨论】:

    标签: jquery knockout.js


    【解决方案1】:

    我建议您在选项中使用checked binding,而不是手动订阅更改事件。

    <input name="optbtn" type="radio" value="All" 
           data-bind="checked: selection" />All
     <input name="optbtn" type="radio" 
           data-bind="checked: selection" value="Selected" />Selected
    

    在你的视图模型中:

    var viewModel = {
        dataOne: ko.observableArray(data1),
        selection: ko.observable("All")
    };
    

    现在您在视图模型上有当前选择,您可以添加一个ko.computed(请参阅doc)进行过滤(每次viewModel.selection 更改时都会触发):

    viewModel.filteredData = ko.computed(function () {
        var str = "<temp>";
        if (viewModel.selection() == "All") return viewModel.dataOne();
        return ko.utils.arrayFilter(viewModel.dataOne(), function (data) {
            stringFromArray = data.display;
            if (stringFromArray.indexOf(str) == 0) {
                return true;
            }
        });
    });
    

    并在您的foreach 中使用此filteredData

    <tbody data-bind="foreach: filteredData">
        <tr>
            ...
        </tr>
     </tbody>
    

    演示JSFiddle.

    注意:如果要根据条件过滤数组,则需要使用ko.utils.arrayFilter,而不是返回第一个找到的项目的ko.utils.arrayFirst。并且你需要从它的第二个参数函数中返回 true/false 来表示是否应该包含一个项目。

    【讨论】:

    • 这个filteredarray是obs数组吗?看不到它的声明位置
    • 请你告诉我们是否可以使用 obs 数组作为过滤数据而不是使用 viewmodel.filteredData?
    • filteredData 是计算属性,它返回一个常规数组,而不是一个可观察的数组。它在viewModel.filteredData = ko.computed(function () { 行中声明。您不能真正单独使用数组进行过滤,因为您需要将项目存储在某处以在用户再次全选时恢复它们,因此无论如何您最终都会得到两个数组。为什么有必要让它可观察或直接使用您的数组?
    • 我们不能复制 obs 数组然后玩它吗?我以前没有使用过这个 viewmodel.filtereddata。让我知道是否可以使用 obs 数组
    • viewmodel.filtereddata 语法没有什么特别之处,它只是为您的viewmodel 添加了一个名为filtereddata 的新属性。您也可以使用类似 :jsfiddle.net/TaF8W/103 的应对方式来做到这一点,但使用 ko.computed 是做这件事的淘汰方式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-20
    • 1970-01-01
    • 1970-01-01
    • 2018-12-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多