2016-06-14 2 views
0

В моей ViewModel я не имею тонны флажков, связанных с простыми строками:Bind флажок для простой строки в Knockout.js

<input type="checkbox" value="CODE" data-bind="checked: itemValue" /> 

До сих пор я использую наблюдаемый массив для решения истина/ложь значение флажка на значение, что мне нужно:

var viewModel = { 
    itemValue: ko.observableArray() 
}; 

Какой самый простой и короткий путь, если есть один, чтобы связать флажок на значение строки без необходимости ссылаться как itemValue[0]?

Что мне нужно, это строковое значение, если отмечено, null, если не отмечено.

В связи с большим количеством наблюдаемых в моем ViewModel, я хотел бы избежать использовать тонны условий как if(itemValue) ...

Fiddle использованием observableArray: https://jsfiddle.net/wu470qup/

ответ

0

Если вы хотите легкую разметку, вы должны будете отслеживать флажки, которые вы хотите отобразить в своей модели viewmodel. Вот самый простой пример:

allValues - это обычный массив строк. Каждая из этих строк получит флажок. itemValues - это наблюдаемый массив строк с установленным флажком. correctedValues - это вычисляемый массив с null для каждого непроверенного поля и строка для каждого отмеченного.

Обратите внимание, что я использую $data для ссылки на текущее строковое значение в foreach.

var allValues = ["CODE", "ANOTHER_VAL"]; 
 
var itemValues = ko.observableArray(); 
 
var correctedValues = ko.computed(function() { 
 
    var all = allValues; 
 
    var checked = itemValues(); 
 

 
    return all.map(function(val) { 
 
    return checked.indexOf(val) === -1 ? null : val; 
 
    }); 
 
}); 
 

 
var viewModel = { 
 
    allValues: allValues, 
 
    itemValues: itemValues, 
 
    correctedValues: correctedValues 
 
}; 
 

 
ko.applyBindings(viewModel);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 

 
<!-- ko foreach: allValues --> 
 
<label> 
 
    <input type="checkbox" data-bind="checked: $parent.itemValues, checkedValue: $data" /> 
 
    <span data-bind="text: $data"><span/> 
 
</label> 
 
<!-- /ko --> 
 
<pre data-bind="text: ko.toJSON($data, null, 2)"></pre>

Более элегантный подход будет создавать ViewModels для каждого флажка. Например:

var CheckboxItem = function() { 
    this.label = ko.observable("CODE"); 
    this.checked = ko.observable(false); 
    this.id = ko.computed(function() { 
    return this.checked() ? this.label() : null; 
    }, this); 
}; 

С шаблоном HTML:

<label> 
    <input type="checkbox" data-bind="checked: checked" /> 
    <input data-bind="value: label" /> 
</label> 

Затем в родительском ViewModel, вы можете хранить наблюдаемый массив CheckBoxItem с и имеют вычисляемый массив, который содержит все id свойства.

+0

Я ценю вашу помощь, действительно, но моя модель-модель глубоко вложена и, кроме того, прибл. ~ 80 компонентов - поэтому в моей ситуации ваше предложение о плоском определении значений не представляется возможным. Я ищу минималистичное решение с меньшим количеством кода и вздутием живота. – deblocker

+0

Хмм, я не думаю, что тогда я действительно понимаю ваш случай. Что-то еще подобное? https://jsfiddle.net/ro2zn0hp/ – user3297291

+0

Что-то, что мой экспорт vm JSON выглядит как {"itemValue": "CODE"}, а не {"itemValue": ["CODE"]}, и я могу ссылаться на него как itemValue, а не itemValue [0] - думать легко как тип ввода = радио без необходимости отображать два варианта – deblocker

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