简体   繁体   中英

Bind a checkbox to a plain string in Knockout.js

In my viewmodel i have tons of checkboxes bound to plain strings:

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

Until now, i'm using an observable array to resolve the true/false value of the checkbox to the value that i need:

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

Which is the simplest and shortest way, if there is one, to bind a checkbox to a string value without the need to reference it as itemValue[0] ?

What i need is the string value if checked, null if unchecked.

Due to the large amount of observables in my viewmodel, i would avoid to use tons of conditions like if(itemValue) ...

Fiddle using an observableArray: https://jsfiddle.net/wu470qup/

If you want effortless markup, you'll have to keep track of the checkboxes you want to render in your viewmodel. Here's the easiest example:

allValues is a regular array of strings. Each of these strings will get a checkbox. itemValues is an observable array of the strings that have a checked checkbox. correctedValues is a computed array with null for each unchecked box, and a string for each checked one.

Notice that I use $data to refer to the current string value in the 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> 

A more elegant approach would be to create viewmodels for each checkbox. For example:

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

With the HTML template:

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

Then, in the parent viewmodel, you can store an observable array of CheckBoxItem s and have a computed array that holds all id properties.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM