0

我可能想多了,但我想做的是从绑定到函数的点击事件中创建一个 observableArray。基本上,当我点击一个按钮时,我需要根据结果过滤event.target.html()并创建一个可观察对象,我可以在foreach页面稍后的循环中使用它。

首先,我有一个按钮。

<button data-bind="click: getData">Button Text</button> 

根据按钮文本过滤结果的功能

self.filterFunction = function(x) {
      // do things here
      return (obj);
}

Click 绑定到该getData函数,该函数从 click 中调用filterFunctionDOM 元素并创建一个可观察数组

self.getData = function(item, event) {
      viewModel.myFilteredData = ko.observableArray(self.filterFunction($(event.target).html()));  

}

然后我循环通过myFilteredData,但惨遭失败。

<!-- ko foreach: myFilteredData -->
       // Generate HTML here
<!-- /ko -->

有些东西告诉我我在逻辑上失败了,有一种更有效的方法可以做到这一点。我还想找出一种myFilteredData基于某些预设进行预填充的方法Button Text,因此可以在单击任何按钮之前在初始页面加载时生成 HTML。

谢谢你。

4

3 回答 3

2

为什么不在视图模型中设置一个 observableArray,创建一个绑定到按钮单击的函数,然后传入每个对象?将带有 a for each 的按钮绑定到某些可观察对象或实体,然后在单击按钮时有一个参数,您将其推入 observableArray

于 2013-06-19T23:37:08.120 回答
2

也许您遇到的问题是您的foreach绑定绑定到与单击后生成的不同的可观察数组。这样想吧。鉴于此视图模型:

{
    myFilteredData: ko.observableArray()
}

...当ko.applyBindings发生这种情况时,Knockout 订阅此ko.observableArray更新,并循环通过(现在为空的)数组。

现在,您的点击处理程序发生:

viewModel.myFilteredData = ko.observableArray(self.filterFunction($(event.target).html()));  

上面建立的订阅没有被触发,因为 observable 数组没有改变;相反,您将其替换为另一个。不幸的是,淘汰赛不知道新的。

我建议不要用新数组替换数组,而是用新数据填充现有数组:

viewModel.myFilteredData(self.filterFunction($(event.target).html()));  
于 2013-06-19T23:52:45.033 回答
2

Solefald,肯定有更好的方法来做到这一点。

首先,将一组您自己的“过滤器”对象添加到您的视图模型,以及一个 ko.computed 以提供您过滤的数据。将过滤器按钮绑定到“过滤器”对象数组。像这样的东西:

var viewModel = function(){
    var self = this;
    self.filters = [
        {buttonText:'Button Text', filterKey:'filterKeyOne'},
        {buttonText:'Other Button Text', filterKey:'filterKeyTwo'}
    ];
    self.selectedFilterKey = ko.observable('none');
    self.setFilter = function(){...}

    self.data = ko.observableArray([...]);
    self.filteredData = ko.computed(function(){...});
}

并像这样绑定:

<div data-bind="foreach: filters">
    <button data-bind="click : $parent.setFilter, text: buttonText"></button>
</div>
<div data-bind="foreach: filteredData">
    ...
</div>

通过让 Knockout 对过滤器按钮进行点击绑定,您将获得整个过滤器对象作为“runFilter”函数中的第一个参数。然后,您可以像这样实现您的过滤器按钮单击处理程序(本例中的“setFilter”):

self.setFilter = function(filterItem){
   self.selectedFilterKey(filterItem.filterKey);
};

通过使“selectedFilterKey”成为可观察对象,您可以将您的过滤数据实现为 ko.computed,当“selectedFilterKey”更改时,它将自动更新 ui,如下所示:

...
self.filteredData = ko.computed(function(){
    //pick the right filter function
    var filterFunction = filterOne;//assign the default filter function
    switch(self.selectedFilterKey()){
        case 'filterKeyOne':
            filterFunction = self.filterOne;//your first filter
        break;
        case 'filterKeyTwo':
            filterFunction = self.filterTwo;//your second filter
        break;
    }
    return ko.utils.arrayFilter(self.data(), function(item){        
        //return true if item passes filter
        return filterFunction(item);
    });
});
...

一种功能方法

如果您想使用更具功能性的编程方法,请尝试在过滤器对象中定义您的过滤器函数。

self.filters = [
    {buttonText:'Button Text', filterFunction:function(item){...}},
    {buttonText:'Other Button Text', filterFunction:function(item){...}}
];

并存储选定的功能,而不是一个键

self.setFilter = function(filterItem){
   self.selectedFilterFunction(filterItem.filterFunction);
};

并跳过 switch 语句

...
self.filteredData = ko.computed(function(){
    return ko.utils.arrayFilter(self.data(), function(item){        
        //return true if item passes filter
        return self.selectedFilterFunction()(item);
    });
});
...

更多信息

如果您想了解有关这种排序方法的更多信息,可以在我的博客上阅读:http ://ryanrahlf.com/sorting-tables-by-column-header-with-knockout-js/

我希望这有帮助!

于 2013-06-20T00:00:46.690 回答