javascript - 可写的计算可观察量真的需要额外的内部可观察量吗?

标签 javascript knockout.js computed-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 中输入的内容并不是真正在里面。

在下面的完整示例中(包括测试输出和注释),我使用额外的可观察对象将数据从 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: 部分,请参阅我注释掉的不需要的代码。

最佳答案

是的,如果你想存储用户输入,你需要一个可观察的。计算对象不存储信息,它仅修改信息。这就像变量和函数之间的区别。函数不会存储它们的值以供以后查看,它只是修改输入并提供输出。

可写的计算可观察量不存储数据。它将数据传递给支持的可观察对象。这就是写入部分的全部要点是获取值并将其存储在某个地方。如果您添加另一个范围来查看 tmpName 的值,您将看到它存储您输入的任何内容,除非选中 cbMirror。

关于javascript - 可写的计算可观察量真的需要额外的内部可观察量吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43103439/

相关文章:

javascript - 定位多个元素的类而不是 id 来使用 javascript 执行操作

javascript - 知道为什么 knockoutjs 会从页面中删除所有 html 内容吗?

javascript - Knockoutjs - 计算可观察值中的引用本地字段

javascript - 如何使用 jQuery 处理 "defile"文本?

javascript - PhantomJS 不接受传递给 page.evaluate() 的函数的参数

javascript - 如何使用带有复选框的 knockoutjs protected observable?

javascript - KnockoutJS 3.1.0 : "with" binding and transitions

arrays - 具有排序和 Foreach 数据绑定(bind)的 knockout 可观察数组

javascript - knockout 修改计算内的 ObservableArray

javascript - 如何使用多个 document.getElementById 的?