KnockoutJS选择选项值

时间:2018-06-20 20:41:45

标签: knockout.js jquery-ui-selectmenu

我正在尝试使用KnockoutJS禁用基于另一个select HTML元素的值的一个select HTML元素

该部分的HTML代码如下:

<label for="searchBy">Search by:</label>
<select id="searchBy" name="searchBy" tabindex="1" data-bind="options: searchBy, value: selectedSearchBy, optionsText: 'searchBy', optionsValue: 'searchBy'"></select>

<label for="searchMethod">Search method:</label>
<select id="searchMethod" name="searchMethod" tabindex="2" data-bind="options: searchMethod, value: selectedSearchMethod, optionsText: 'searchMethod', optionsValue: 'searchMethod', disable: searchByDOB"></select>

和相关的KonckutJS代码:

this.searchByDOB = ko.observable(false);

this.searchBy = ko.observableArray([{searchBy: 'Name', value: 'name'},{searchBy: 'Date of Birth', value: 'dob'},{searchBy: 'User ID', value: 'id'}]);

this.selectedSearchBy = ko.observable();
this.searchMethod = ko.observableArray([{searchMethod: 'beginning with', value: 's%'},{searchMethod: 'containing', value: '%s%'},{searchMethod: 'ending with', value: '%s'}]);
this.selectedSearchMethod = ko.observable();

this.selectedSearchBy.subscribe(function(latest) {
  console.log("Search by: " + this.selectedSearchBy().value);
    if(this.selectedSearchBy().value == 'dob')
    {
      this.searchByDOB = ko.observable(true);
    }

}, this);

但是我得到的是this.selectedSearchBy().valueundefinied

我缺少了什么?我应该将逻辑更改为更改事件吗?

3 个答案:

答案 0 :(得分:2)

您的订阅首次触发是在页面加载后立即触发,因此尚无选择。 selectedSearchBy是未定义的,就像它说的那样,因此您不能在其上调用“ .value”。

您可以为selectedSearchBy提供一个与searchBy数组中的选项之一匹配的默认值,或者可以在调用.value之前检查selectedSearchBy的值。

this.selectedSearchBy.subscribe(function(latest) {
    if(this.selectedSearchBy() && this.selectedSearchBy().value == 'dob')
    {
      this.searchByDOB = ko.observable(true);
    }
}, this);

答案 1 :(得分:1)

没有.value属性;正是这提供了未定义的错误。

只需通过this.selectedSearchBy()读取值即可。

还可以通过this.searchByDOB(true)而不是值分配来写属性。

编辑

subscribe方法必须同时包含enable this.searchByDOB(true)和disable this.searchByDOB(false)语句,否则,一旦禁用,下拉列表将保持禁用状态。

此外,仅通过(this.selectedSearchBy() === 'dob')进行检查即可。
(尽管在这里没什么区别,但=====优先。)

function ViewModel()
{

    this.searchByDOB = ko.observable(false);

    this.searchBy = ko.observableArray([
        {searchBy: 'Name', value: 'name'},
        {searchBy: 'Date of Birth', value: 'dob'},
        {searchBy: 'User ID', value: 'id'}
      ]);

    this.selectedSearchBy = ko.observable();
    
    this.searchMethod = ko.observableArray([
        {searchMethod: 'beginning with', value: 's%'},
        {searchMethod: 'containing', value: '%s%'},
        {searchMethod: 'ending with', value: '%s'}
        ]);
        
    this.selectedSearchMethod = ko.observable();

    this.selectedSearchBy.subscribe(function(latest) {
        var isSearchByDob = (this.selectedSearchBy() === 'dob');        
        this.searchByDOB(isSearchByDob);
        }, this
        );
}

var vm = new ViewModel();
ko.applyBindings(vm);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

<label for="searchBy">Search by:</label>
<select id="searchBy" name="searchBy" tabindex="1" data-bind="options: searchBy, value: selectedSearchBy, optionsText: 'searchBy', optionsValue: 'value'"></select>

<label for="searchMethod">Search method:</label>
<select id="searchMethod" name="searchMethod" tabindex="2" data-bind="options: searchMethod, value: selectedSearchMethod, optionsText: 'searchMethod', optionsValue: 'value', disable: searchByDOB"></select>

答案 2 :(得分:0)

有效的解决方案是两个答案的结合。

未正确设置第一个DOM元素以获得正确的值:

<label for="searchBy">Search by:</label>
<select id="searchBy" name="searchBy" tabindex="1" data-bind="options: searchBy, value: selectedSearchBy, optionsText: 'searchBy', optionsValue: 'value'"></select>

<label for="searchMethod">Search method:</label>
<select id="searchMethod" name="searchMethod" tabindex="2" data-bind="options: searchMethod, value: selectedSearchMethod, optionsText: 'searchMethod', optionsValue: 'value', disable: searchByDOB"></select>

然后使用适合该参数的JS:

this.selectedSearchBy =  ko.observable({searchBy: 'Name', value: 'name'});

...

       this.selectedSearchBy.subscribe(function(latest) {
            if(this.selectedSearchBy() && this.selectedSearchBy() == 'dob')
            {
                this.searchByDOB(true);
            }
        }, this)

感谢@JasonSpake和@pfx