KnockoutJS:通过点击绑定创建一个可观察对象
KnockoutJS: Create an observable from click binding
我可能想太多了,但我想做的是创建一个observableArray从点击事件绑定到一个函数。基本上,当我点击一个按钮时,我需要根据event.target.html()
过滤结果,并创建一个可观察对象,以便在页面后面的foreach
循环中使用。
首先我有一个按钮。
<button data-bind="click: getData">Button Text</button>
基于Button Text筛选结果的函数
self.filterFunction = function(x) {
// do things here
return (obj);
}
Click与getData
函数绑定,该函数使用Click中的DOM元素调用filterFunction
并创建一个可观察数组
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可以在初始页面加载,点击任何按钮之前生成。
谢谢。
也许你的问题是你的foreach
绑定绑定到一个不同的可观察数组,而不是你在点击后生成的。这样想吧。给定这个视图模型:
{
myFilteredData: ko.observableArray()
}
…当ko.applyBindings
发生时,Knockout订阅此ko.observableArray
进行更新,并循环遍历(现在为空)数组。
viewModel.myFilteredData = ko.observableArray(self.filterFunction($(event.target).html()));
上面建立的订阅没有被触发,因为可观察数组没有改变;相反,你用另一个代替了它。不幸的是,Knockout不知道这个新版本。
我建议不要用新数组替换数组,而是用新数据填充现有数组:
viewModel.myFilteredData(self.filterFunction($(event.target).html()));
为什么不直接在视图模型中设置一个observableArray,创建一个绑定到button click的函数,然后传入每个对象呢?用a for each将按钮绑定到一些可观察对象或实体,然后在按钮上单击一个参数,将其推入observableArray
Solefald,肯定有更好的方法。
首先,向视图模型添加一个自己的"过滤器"对象数组,以及一个ko.computed来提供过滤后的数据。将过滤器按钮绑定到"filter"对象数组。像这样:
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"成为一个可观察对象,你可以将你的filteredData实现为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/
我希望这对你有帮助!
- 如果使用 lodash 将属性存在于另一个对象中,则向对象添加属性
- Javascript(Angular)从一个对象数组到第二个数组查找值
- 对一个对象使用reduce可以返回一个没有't在数组中包含目标字母
- AngularJS&JSON-从Previous&下一个对象
- jQuery$.inArray()总是返回-1和一个对象数组
- javascript处理一个对象数组以获得一个新的对象数组
- javascript函数,它接受两个输入:一个对象和一个键,并返回对象中该键的相应值
- 你能用来自数组的属性名称生成一个对象吗
- 预期响应包含一个对象,但在angular js中得到一个数组错误
- Protractor:element.getText()返回一个对象,而不是String
- 如何使用jQuery添加另一个对象的高度作为边距
- 计算从一个对象到另一个对象的路径并沿其移动
- 如何将一个对象添加到每个对象数组中
- 为了避免创建全局变量,可以将所有变量分配给一个对象吗
- 将javascript对象(属性+值)合并到一个对象中
- 尝试简化检查对象键是否为true并将其推送到另一个对象
- 从 javascript 中的对象方法返回一个对象
- 响应应包含一个对象,但得到的却是GET操作的数组
- js:如何制作一个循环,将20个不同的东西添加到一个对象中
- 用javascript创建另一个对象的实例