2013-07-31 2 views
1

У меня есть страница с выделенным ящиком и поле ввода, связанное с тем же значением. Идея состоит в том, что обычно выбирается значение из выбора, однако пользователь должен также иметь возможность вводить произвольную строку в поле ввода. Проблема в том, что если я введу что-то, отсутствующее в select, из-за привязки, значение будет установлено на первый элемент в select.Обмен нокаутом и привязка обмена текстовыми полями

Это поведение я хочу добиться:

Пользователь выбирает значение из выбора

  1. задано значение выбранного элемента.
  2. Ввод обновляется с выбранным значением.

Пользователь вводит текст на входе

  1. Значение устанавливается на введенный текст.
  2. Выбрать не изменяется если Значение присутствует в коллекции доступных значений.

Другими словами, я хочу, чтобы последний измененный элемент управления был действительным значением. Но я также хочу, чтобы оба элемента управления были в актуальном состоянии , пока данное значение действительно для этого элемента управления.

Мой код выглядит следующим образом:

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

Я ищу сделать то же самое, и в то время как вы сделали решить в вашей скрипке я согласен, что это не самое красивое решение. Вы когда-нибудь находили более простой способ достичь этого? – powerbuoy

+0

Простите, но это так давно, я даже не помню проблемы и не использовал ее. Поэтому у меня нет хорошего решения для вас. – Alxandr

ответ

1

Как вы можете видеть, я добавляю наблюдаемое значение inputValue, которое привязано к текстовому вводу. Я также добавляю вычисленный named 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

Я надеюсь, что это помогает.

+0

Хотя мне не очень нравится, как вы можете получить дубликаты значений в элементе select, код дал мне представление о том, как решить проблему, поэтому я отмечаю это как решение. – Alxandr

+0

@Alexandr Планируйте поделиться своим созданным решением? –

+0

Или это тот, что упоминается в редактировании сообщения? –

0

Вместо этого вы можете использовать вместо этого вычисляемое наблюдаемое, которое обновляется, только если значение имеет смысл.

Я сделал пример, когда я добавил подпись к выбору.В результате он автоматически не выбирает первое значение, но вместо этого пытается установить неопределенное значение, когда он считывает значение, которое не входит в массив Set.

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

Чтобы сделать это, конструктор функции вместо литерал объекта будет проще, потому что тогда вы можете получить доступ к Value наблюдаемым через 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/

+0

Это не работает вообще. Попробуйте ввести что-то фиктивное в текстовое поле. Вам не разрешено вводить его. – Alxandr

Смежные вопросы