2

我有一个带有选择的页面和一个绑定到相同值的输入框。这个想法是通常人们会从选择中选择一个值,但是,用户也应该能够在输入框中输入任意字符串。问题是,如果我输入了选择中不存在的内容,由于绑定,该值被设置为选择中的第一项。

这是我想要实现的行为:

用户从选择中选择值

  1. 值设置为所选项目。
  2. 输入用选定的值更新。

用户在输入中输入文本

  1. 值设置为输入的文本。
  2. Select 不会改变,除非Value 存在于可用值的集合中。

换句话说,我想要的是最后更改的控件成为有效值。但我也希望这两个控件都是最新的,只要给定值对该控件有效

我的代码如下所示:

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/),但是它真的不漂亮,必须有更好的方法来解决这个问题。

4

2 回答 2

1

如您所见,我添加了一个绑定到文本输入的 inputValue 可观察对象。我还添加了一个计算的命名 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);
});

见小提琴

我希望它有所帮助。

于 2013-07-31T08:12:54.777 回答
0

您可以让 select 使用计算的 observable 来代替,它仅在值有意义时才更新。

我做了一个例子,我在选择中添加了一个标题。结果是它不会自动选择第一个值,而是在读取未包含在Set数组中的值时尝试设置未定义的值。

<select type="text" class="form-control input-small" data-bind="options: Set, value: SelectValue, optionsCaption: 'Other value'"></select>

要做到这一点,构造函数而不是对象字面量会更容易,因为这样你就可以通过引用访问Valueobservable 。self

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); 
                 }
    });
}

http://jsfiddle.net/b2RwG/4/

于 2013-07-31T08:19:31.883 回答