我有一个页面,其中一个select和一个输入框绑定到相同的值。我们的想法是,通常会从select中选择一个值,但是,用户也应该能够在输入框中输入任意字符串。问题是,如果我输入select中不存在的内容,由于绑定,该值将设置为select中的第一项。
这是我想要实现的行为:
用户从选择
中选择值用户在输入中输入文字
换句话说,我想要的是最后一次更改的控件是有效的值。但是,只要给定值对该控件有效,我也希望两个控件都是最新的。
我的代码如下所示:
JS
var viewModel = { Value: ko.observable('1'), Set: ['1', '2', '3'] };
ko.applyBindings(viewModel);
HTML
<!-- ko if: Set.length > 1 || (Set.length > 0 && Set[0] != '') -->
<select type="text" class="form-control input-small" data-bind="options: Set, value: Value">
</select>
<!-- /ko -->
<input class="form-control input-small" data-bind="value: Value" style="margin-top: 5px;" />
这是一个显示代码当前工作方式的jsfiddle:http://jsfiddle.net/b2RwG/
[编辑]
我找到了一个有效的解决方案(http://jsfiddle.net/b2RwG/2/),但它真的不太漂亮,必须有更好的方法来解决这个问题。
答案 0 :(得分:1)
如您所见,我添加了一个绑定到文本输入的inputValue observable。 我还添加了一个计算名为virtualSet,其中包含原始项和新项(来自文本输入)。 我输入inputValue所以当你输入时会自动设置选择。
var viewModel = {
inputValue: ko.observable('1'),
Value: ko.observable('1'),
Set: ['1', '2', '3']
};
viewModel.virtualSet = ko.computed({
read: function () {
var vs = this.Set.slice(0);
if (this.inputValue() && this.inputValue().length)
vs.unshift(this.inputValue());
return vs;
},
owner: viewModel
});
viewModel.inputValue.subscribe(function (value) {
viewModel.Value(value);
});
<强> See fiddle 强>
我希望它有所帮助。
答案 1 :(得分:0)
您可以让select使用计算的observable,只有在值有意义时才会更新。
我做了一个例子,我在select中添加了一个标题。结果是它不会自动选择第一个值,而是在读取未包含在Set
数组中的值时尝试设置未定义的值。
<select type="text" class="form-control input-small" data-bind="options: Set, value: SelectValue, optionsCaption: 'Other value'"></select>
为此,构造函数而不是对象文字将使其更容易,因为您可以通过Value
引用访问self
observable。
function ViewModel() {
var self=this;
this.Value = ko.observable('1');
this.Set = ['1', '2', '3'];
this.SelectValue= ko.computed({
read: function() {
var val = self.Value();
return val;
},
write: function(value) {
if(value) self.Value(value);
}
});
}