我正在尝试使用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().value
是undefinied
我缺少了什么?我应该将逻辑更改为更改事件吗?
答案 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