我应该在哪里使用带有Knockout Computed和数组的括号

时间:2017-02-22 14:57:49

标签: knockout.js

我正在组合一个Options绑定和一个Computed,并在Firebug控制台中收到错误:

TypeError:this.selectedCountryNeverNull未定义

这是ViewModel的相关部分:

    // Constructor for an object with two properties
    var Country = function (name, population) {
        this.countryName = name;
        this.countryPopulation = population;
    };

    var viewModel = {
        availableCountries: ko.observableArray([
            new Country("UK", 65000000),
            new Country("USA", 320000000),
            new Country("Sweden", 29000000)
        ]),
        selectedCountry: ko.observable(), // Nothing selected by default
        selectedCountryNeverNull: ko.observable(), // has default
        selectedCountryDesc: ko.computed(function () { return '*' + this.selectedCountryNeverNull.countryName + '*'; }, this)
    };

这是选择:

    <select data-bind="options: availableCountries,
                   optionsText: 'countryName',
                   value: selectedCountryNeverNull"></select>

我遗漏了optionsCaption:,因此第一个数组元素是默认值,值永远不为空。

Firebug说错误出现在ko.computed行,我试图在这里和那里添加()个括号,但没有用。

我想做更多更大ko.computed的事情,但在淘汰网站的一个例子的扩展中分离了我的问题。

感谢您帮助我们了解一般的括号问题,特别是。

1 个答案:

答案 0 :(得分:3)

我发现您的代码有三个问题:

    您在this中的
  1. ko.computed指的是Window,而不是viewModel
  2. select绑定在applyBindings时设置其值,因此在短暂的一段时间内,selectedCountryNeverNull实际上是未定义的。这意味着您必须手动设置默认值或检查已编译的虚假值
  3. 在计算中,您需要使用()获取selectedCountryNeverNull的值并创建依赖关系。
  4. 关于如何修复所有三个的示例:

    1. 使用构造函数和new关键字来管理this
    2. 默认为计算(|| {}
    3. 中的空对象
    4. 调用计算(()
    5. 中的observable

      &#13;
      &#13;
      // Constructor for an object with two properties
      var Country = function(name, population) {
        this.countryName = name;
        this.countryPopulation = population;
      };
      
      var ViewModel = function() {
        this.availableCountries = ko.observableArray([
          new Country("UK", 65000000),
          new Country("USA", 320000000),
          new Country("Sweden", 29000000)
        ]);
        
        this.selectedCountry = ko.observable(); // Nothing selected by default
        
        this.selectedCountryNeverNull = ko.observable(); // has default
        
        this.selectedCountryDesc = ko.computed(function() {
          return '*' + (this.selectedCountryNeverNull() || {}).countryName + '*';
        }, this);
      };
      
      ko.applyBindings(new ViewModel());
      &#13;
      <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
      <select data-bind="options: availableCountries,
                         optionsText: 'countryName',
                         value: selectedCountryNeverNull"></select>
                         
      Selection: <span data-bind="text: selectedCountryDesc"></span>
      &#13;
      &#13;
      &#13;