Where should I use parentheses with Knockout Computed and arrays

浪子不回头ぞ 提交于 2020-01-17 03:28:04

问题


I am combining an Options binding and a Computed, and am getting the error in the Firebug console:

TypeError: this.selectedCountryNeverNull is undefined

This is the relevant part of the 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)
    };

and this is the select:

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

I left out the optionsCaption: so that the first array element is the default, and the value is never null.

Firebug says the error is in the ko.computed line, and I tried to add () parentheses here and there, but with no avail.

I want to do much bigger ko.computed stuff, but isolated my problem in this extension of an example from the knockout site.

Thanks for any help in trying to understand the parentheses issues in general and mine particular.


回答1:


I see three problems with your code:

  1. this in your ko.computed refers to Window, not to viewModel,
  2. The select binding sets its value at the time of applyBindings, so for a brief period of time, selectedCountryNeverNull is actually undefined. This means you'll have to set it with a default manually or check for falsey values in your comptued
  3. In the computed, you'll need to use the () to get selectedCountryNeverNull's value and create a dependency.

An example on how to fix all three:

  1. Use a constructor and the new keyword to manage this,
  2. Default to an empty object in the computed ( || {} )
  3. Call the observable in the computed ( () )

// 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());
<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>


来源:https://stackoverflow.com/questions/42394966/where-should-i-use-parentheses-with-knockout-computed-and-arrays

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!