我正在尝试使用可写的计算observable,但实际上并没有得到它为什么我只是输入它就无法在observable中获取一些数据。我发现我需要额外的observable来复制write:
到read:
的内容,这看起来很奇怪。
self.fullName = ko.pureComputed({
read: function () {
return ...data from other observables to show in the observable;
},
write: function (value) {
// value is the content in the input
// can be sent to other observables
},
owner: self
});
我发现在上面的模型中,你在observable中输入的内容并不在里面。
在下面的完整示例中(包括测试输出和注释),我使用额外的observable将数据从write:
复制到read:
。在我的项目中至关重要的是复选框,以决定是否通过键入其中一个来获得两个相同的可观察量,或者通过键入两个可观察量来区别对待。
<!DOCTYPE html>
<html lang="en">
<head>
<title>Writable computed observables</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script src='https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.1/knockout-min.js'></script>
</head>
<body>
<h1>Writable computed observables</h1>
<p>See: <a href="http://knockoutjs.com/documentation/computed-writable.html">Knockout Doc</a></p>
<h2>Original example</h2>
<div>
First name: <input data-bind="textInput: firstName" />
<span data-bind="text: firstName"></span>
</div>
<div>
Last name: <input data-bind="textInput: lastName" />
<span data-bind="text: lastName"></span>
</div>
<div class="heading">
Hello, <input data-bind="textInput: fullName" />
<span data-bind="text: fullName"></span>
</div>
<h2>My example</h2>
<div>
Name: <input data-bind="textInput: Name" />
<span data-bind="text: Name"></span>
</div>
<div>
Mirror first name? <input type="checkbox" data-bind="checked: cbMirror" />
<span data-bind="text: cbMirror"></span>
</div>
<script>
function MyViewModel() {
var self = this;
// example from knockout site:
self.firstName = ko.observable('Planet');
self.lastName = ko.observable('Earth');
self.fullName = ko.pureComputed({
read: function () {
//return;
return self.firstName() + " " + self.lastName();
},
write: function (value) {
// value is the content in the input field, visible on form,
// but apparently not yet in the observable.
// now copy this value to first/last-name observables,
// that in turn copy it to the read-function,
// that returns it to the observable.
var lastSpacePos = value.lastIndexOf(" ");
if (lastSpacePos > 0) { // Ignore values with no space character
self.firstName(value.substring(0, lastSpacePos)); // Update "firstName"
self.lastName(value.substring(lastSpacePos + 1)); // Update "lastName"
}
},
owner: self
});
// checkbox whether or not to mirror between two fields
self.cbMirror = ko.observable(false);
// this observable is to help the writable computed observable to copy input from write() to read()
self.tmpName = ko.observable();
// the writable computed observable that may mirror another field, depending on the checkbox
self.Name = ko.pureComputed({
read: function () {
return self.cbMirror() ? self.firstName() : self.tmpName();
},
write: function (value) {
//if (self.cbMirror()){
// self.firstName(value);
//}else{
self.tmpName(value);
//}
},
owner: self
});
}
ko.applyBindings(new MyViewModel());
</script>
</body>
</html>
这个问题因此:在没有额外可观察write:
的情况下直接从read:
到self.tmpName
获取一些内容真的没有更好的方法吗?
更新
根据下面的答案中获得的理解,我可以简化示例代码的write:
部分,查看我注释掉的不需要的代码。
答案 0 :(得分:1)
是的,如果要存储用户输入,则需要一个observable。计算出的信息不存储它只修改它的信息。这就像变量和函数之间的区别。函数不会存储它们的值,以便以后查看它只修改输入并给出输出。
可写计算的observable不存储数据。它将数据传递给后备可观察对象。写入部分的全部要点是获取值并将其存储在某处。如果添加另一个范围来查看tmpName的值,除非选中cbMirror,否则您将看到它存储了您输入的内容。