Computed Observable基础教程文档
收录于 2023-04-20 00:10:05 · بالعربية · English · Español · हिंदीName · 日本語 · Русский язык · 中文繁體
Computed Observable 是一种依赖于一个或多个 Observable 并在其底层 Observable(依赖项)发生变化时自动更新的函数。
计算出的 Observable 可以链接起来。
语法
this.varName = ko.computed(function(){ ... ... // function code ... },this);
示例
让我们看看下面的例子,它演示了 Computed Observables 的使用。
<!DOCTYPE html> <head > <title>KnockoutJS Computed Observables</title> <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.1.0.js"></script> </head> <body> <p>Enter first number: <input data-bind = "value: a" /></p> <p>Enter second number: <input data-bind = "value: b"/></p> <p>Average := <span data-bind="text: totalAvg"></span></p> <script> function MyViewModel() { this.a = ko.observable(10); this.b = ko.observable(40); this.totalAvg = ko.computed(function() { if(typeof(this.a()) !== "number" || typeof(this.b()) !== "number") { this.a(Number(this.a())); //convert string to Number this.b(Number(this.b())); //convert string to Number } total = (this.a() + this.b())/2 ; return total; },this); } ko.applyBindings(new MyViewModel()); </script> </body> </html>
在以下几行中,前两行用于接受输入值。第三行打印这两个数字的平均值。
<p>Enter first number: <input data-bind = "value: a" /></p> <p>Enter second number: <input data-bind = "value: b"/></p> <p>Average := <span data-bind = "text: totalAvg"></span></p>
在下面几行中,Observables
a 和
b 的类型在 ViewModel 中第一次初始化时是数字。但是,在 KO 中,从 UI 接受的每个输入默认都是字符串格式。因此需要将它们转换为Number,以便对其进行算术运算。
this.totalAvg = ko.computed(function() { if(typeof(this.a()) !== "number" || typeof(this.b()) !== "number") { this.a(Number(this.a())); //convert string to Number this.b(Number(this.b())); //convert string to Number } total = (this.a() + this.b())/2 ; return total; },this);
在下一行中,计算的平均值显示在 UI 中。请注意,totalAvg 的数据绑定类型只是文本。
<p>Average := <span data-bind = "text: totalAvg"></span></p>
输出
让我们执行以下步骤来看看上面的代码是如何工作的-
将上述代码保存在 computed-observable.htm 文件中。
在浏览器中打开此 HTML 文件。
在文本框中输入任意 2 个数字,然后观察计算平均值。
管理"这个"
请注意,在上面的示例中,第二个参数作为
this 提供给 Computed 函数。如果不提供
this,就不可能引用 Observables
a() 和
b()。
为了克服这个问题,使用了
self 变量来保存
this 的引用。这样做,无需在整个代码中跟踪
this。相反,可以使用
self。
下面的 ViewModel 代码是使用 self 为上面的例子重写的。
function MyViewModel(){ self = this; self.a = ko.observable(10); self.b = ko.observable(40); this.totalAvg = ko.computed(function() { if(typeof(self.a()) !== "number" || typeof(self.b()) !== "number") { self.a(Number(self.a())); //convert string to Number self.b(Number(self.b())); //convert string to Number } total = (self.a() + self.b())/2 ; return total; }); }
纯计算可观察量
计算的 Observable 应该声明为
Pure Computed Observable,如果该 Observable 只是计算和返回值,而不是直接修改其他对象或状态。 Pure Computed Observables 帮助 Knockout 有效地管理重新评估和内存使用。
明确通知订阅者
当 Computed Observable 返回原始数据类型值(String、Boolean、Null 和 Number)时,当且仅当实际值发生更改时,才会通知其订阅者。这意味着如果 Observable 接收到的值与之前的值相同,则不会通知其订阅者。
您可以使用
notify 语法使 Computed Observables 始终明确通知观察者,即使新值与旧值相同。
myViewModel.property = ko.pureComputed(function() { return ...; // code logic goes here }).extend({ notify: 'always' });
限制变更通知
太多昂贵的更新会导致性能问题。您可以使用
rateLimit 属性限制从 Observable 接收的通知数量,如下所示。
// make sure there are updates no more than once per 100-millisecond period myViewModel.property.extend({ rateLimit: 100 });
确定一个属性是否通过计算可观察
在某些情况下,可能有必要确定属性是否为计算可观察对象。以下函数可用于识别 Observable 的类型。
Sr.No. | 功能 |
1 |
ko.isComputed
如果属性是计算可观察的,则返回
true。
|
2 |
ko.isObservable
如果属性是 Observable、Observable 数组或计算 Observable,则返回
true。
|
3 |
ko.isWritableObservable
如果 Observable、Observable 数组或 Writable Computed Observable,则返回
true。 (这也称为 ko.isWriteableObservable)
|
可写的计算观测值
Computed Observable 派生自一个或多个其他 Observable,因此它是只读的。但是,有可能使 Computed Observable 可写。为此,您需要提供适用于写入值的回调函数。
这些可写的 Computed Observables 就像普通的 Observables 一样工作。此外,它们需要构建自定义逻辑来干扰读取和写入操作。
可以使用如下链接语法为许多 Observable 或 Computed Observable 属性赋值。
myViewModel.fullName('Tom Smith').age(45)
示例
以下示例演示了 Writable Computable Observable 的使用。
<!DOCTYPE html> <head > <title>KnockoutJS Writable Computed Observable</title> <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.3.0.js"></script> </head> <body> <p>Enter your birth Date: <input type = "date" data-bind = "value: rawDate" ></p> <p><span data-bind = "text: yourAge"></span></p> <script> function MyViewModel() { this.yourAge = ko.observable(); today = new Date(); rawDate = ko.observable(); this.rawDate = ko.pureComputed ({ read: function() { return this.yourAge; }, write: function(value) { var b = Date.parse(value); // convert birth date into milliseconds var t = Date.parse(today); // convert todays date into milliseconds diff = t-b; // take difference var y = Math.floor(diff/31449600000); // difference is converted // into years. 31449600000 //milliseconds form a year. var m = Math.floor((diff % 31449600000)/604800000/4.3); // calculating // months. // 604800000 // milliseconds // form a week. this.yourAge("You are " + y + " year(s) " + m +" months old."); }, owner: this }); } ko.applyBindings(new MyViewModel()); </script> </body> </html>
在上面的代码中,
rawDate 是从 UI 接受的 pureComputed 属性。
yourAge Observable 派生自
rawDate。
JavaScript 中的日期以毫秒为单位进行处理。因此,两个日期(今天日期和出生日期)都被转换为毫秒,然后它们之间的差异以年和月为单位转换回来。
输出
让我们执行以下步骤来看看上面的代码是如何工作的-
将上述代码保存在 writable_computed_observable.htm 文件中。
在浏览器中打开此 HTML 文件。
输入任何出生日期并观察年龄计算。