您的位置:首页 > Web前端 > JavaScript

KnockoutJS 3.X API 第七章 其他技术(6) 使用“fn”添加自定义函数

2016-10-19 11:13 447 查看
有时,您可能会通过向Knockout的核心值类型添加新功能来寻找机会来简化您的代码。 您可以在以下任何类型中定义自定义函数:





因为继承,如果你附加一个函数到ko.subscribable,它将可用于所有其他的。 如果你附加一个函数到ko.observable,它将被ko.observableArray继承而不是ko.computed继承。 要附加自定义函数,请将其添加到以下可扩展性点之一:
ko.subscribable.fn
ko.observable.fn
ko.observableArray.fn
ko.computed.fn

然后,您的自定义函数将可用于从该点开始创建的所有类型的值。 注意:最好仅将此可扩展点用于真正适用于各种场景的自定义函数。 如果你只打算使用一次,你不需要添加自定义函数到这些命名空间。

示例:可见数组的过滤视图

这里有一种方法来定义一个过滤器按属性函数,将在所有后续创建的ko.observableArray实例上可用:

ko.observableArray.fn.filterByProperty = function(propName, matchValue) {
return ko.pureComputed(function() {
var allItems = this(), matchingItems = [];
for (var i = 0; i < allItems.length; i++) {
var current = allItems[i];
if (ko.unwrap(current[propName]) === matchValue)
matchingItems.push(current);
}
return matchingItems;
}, this);
}

这返回一个新的计算值,它提供了数组的过滤视图,同时保持原始数组不变。 因为过滤的数组是一个计算的observable,所以当底层数组发生变化时,它将被重新计算。

以下实例演示如何使用此:

All tasks ( )

Done tasks ( )

UI源码:

<h3>All tasks (<span data-bind="text: tasks().length"> </span>)</h3>
<ul data-bind="foreach: tasks">
<li>
<label>
<input type="checkbox" data-bind="checked: done" />
<span data-bind="text: title"> </span>
</label>
</li>
</ul>

<h3>Done tasks (<span data-bind="text: doneTasks().length"> </span>)</h3>
<ul data-bind="foreach: doneTasks">
<li data-bind="text: title"></li>
</ul>

视图模型源码:

function Task(title, done) {
this.title = ko.observable(title);
this.done = ko.observable(done);
}
ko.observableArray.fn.filterByProperty = function(propName, matchValue) { return ko.pureComputed(function() { var allItems = this(), matchingItems = []; for (var i = 0; i < allItems.length; i++) { var current = allItems[i]; if (ko.unwrap(current[propName]) === matchValue) matchingItems.push(current); } return matchingItems; }, this); }

function AppViewModel() {
this.tasks = ko.observableArray([
new Task('Find new desktop background', true),
new Task('Put shiny stickers on laptop', false),
new Task('Request more reggae music in the office', true)
]);

// Here's where we use the custom function
this.doneTasks = this.tasks.filterByProperty("done", true);
}

ko.applyBindings(new AppViewModel());

这不是强制性的

如果你倾向于过滤可观察的数组很多,添加一个filterByProperty全局可见的数组可能会使你的代码更整洁。 但是如果你只需要偶尔过滤,你可以选择不附加到ko.observableArray.fn,而只是手工构造doneTasks如下:

this.doneTasks = ko.pureComputed(function() {
var all = this.tasks(), done = [];
for (var i = 0; i < all.length; i++)
if (all[i].done())
done.push(all[i]);
return done;
}, this);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: