【问题标题】:knockout computed observable write not working for plain object containing atomic observables淘汰计算的可观察写入不适用于包含原子可观察的普通对象
【发布时间】:2014-04-24 13:08:01
【问题描述】:

我已经从简单的 observable 创建了一个计算 observable,如下所示:

  • this.fullDetails 是计算出来的 observable。
  • this.computeFullDetails 是计算的读取函数。
  • this.writeToComponents 是计算的写入函数。

当我修改与原子可观察对象对应的输入框时,计算属性会被修改,但是当我修改计算属性时,原子属性不会更新。 我可以用另一种方法来完成这样的事情吗?

请看这个小提琴http://jsfiddle.net/saurabh0jha/wqpZ9/

function PersonViewModel()
{
    this.firstName = ko.observable("");
    this.lastName = ko.observable("");
    this.phoneNos = ko.observable(0);
    this.address = ko.observable("");
    this.computeFullDetails = function(){
            retObj = {};
            retObj.firstName=ko.observable(this.firstName());
            retObj.lastName=ko.observable(this.lastName());
            retObj.phoneNos=ko.observable(this.phoneNos());
            retObj.address=ko.observable(this.address());
            return retObj; 
        };
    
    this.writeToComponents = function(value){
                this.firstName(value.firstName());
                this.lastName(value.lastName());
                this.phoneNos(value.phoneNos());
                this.address(value.address());
            };
        
    this.fullDetails = ko.computed(
        {
            read:this.computeFullDetails,
            write:this.writeToComponents,
        },this);

}


var vm = new PersonViewModel();
ko.applyBindings(vm);

HTML

<html lang='en'>
<head>
  <title>Hello, Knockout.js</title>
  <meta charset='utf-8' />
  <link rel='stylesheet' href='style.css' />
</head>
<body>
    <h2>atomic</h2>
    <input data-bind="value: firstName" style="display:block" />
    <input data-bind="value: lastName" style="display:block"/>
    <input data-bind="value: phoneNos"style="display:block" />
    <input data-bind="value: address" style="display:block"/>
    <h2>computed</h2>
    <input data-bind="value: fullDetails().firstName" style="display:block"/>
    <input data-bind="value:fullDetails().lastName" style="display:block"/>
    <input data-bind="value: fullDetails().phoneNos"style="display:block" />
    <input data-bind="value: fullDetails().address"style="display:block" />

    <script type='text/javascript' src='knockout-2.2.0.js'></script>
    <script type='text/javascript' src='2computedObservables.js'>   </script>
</body>
</html>

【问题讨论】:

  • 请注意,绑定到fullDetails() 的属性(例如fullDetails().firstName)实际上不会导致writeToComponents 在文本框值更改时触发。
  • 这是我的确切问题。如果计算是使用这样的字符串操作计算的,则相同的回写将起作用返回 self.firstName+ " " +self.lastName。但是当我想写回嵌套在对象中的可观察对象时,它不起作用。不知道是否有一种简单的方法可以做到这一点,因为我不习惯编写自定义绑定。

标签: javascript knockout.js computed-observable


【解决方案1】:

不确定您要做什么。

你的代码的问题是你没有订阅你在computeFullDetails中返回的可观察对象。

你可以试试这个:

<input data-bind="value: fullDetailsFirstName" style="display:block" />

this.fullDetailsFirstName = ko.computed({
    read: function () {
        return self.firstName();
    },
    write: function (newValue) {
        self.firstName(newValue)
    }
});

示例(仅更改了名字): http://jsfiddle.net/nyothecat/VJ4th/1/

【讨论】:

  • 对不起,没有把事情说清楚..我试图从一个页面中获取原子属性,使用这些输入进行 AJAX 调用,当调用返回时更新另一个页面。为简单起见,我创建了上面的示例通过将两个页面放在一个中。我正在使用计算的 observable 并将其转换为 JS 作为 AJAX 的请求,并使用响应来更新计算的 observable。
【解决方案2】:

这个:

retObj.firstName=ko.observable(this.firstName());

用旧的值创建一个 new observable。因此,每次调用 computeFullDetails 时,您都会丢失所有旧依赖项。

绑定到以前的fullDetails().firstName 的所有内容将永远不会再次更新。

如果我理解正确,你想要这样的东西:

function PersonViewModel() {
    this.firstName = ko.observable("");
    this.lastName  = ko.observable("");
    this.phoneNos  = ko.observable(0);
    this.address   = ko.observable("");

    this.anyAttribute = ko.computed(function() {
      this.firstName();
      this.lastName();
      this.phoneNos();
      this.address();

      // what this returns is not important, its
      // only job is to notify subscribers when any
      // dependency has changed
    });

    this.anyAttribute.subscribe(function() {
      // do here whatever you need to do when any
      // of the attributes has changed
    });
}

var vm = new PersonViewModel();
ko.applyBindings(vm);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    • 2013-05-30
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 2014-06-23
    • 2015-10-05
    相关资源
    最近更新 更多