2016-06-14 7 views
0

In meinem Viewmodel Ich habe Tonnen von Kontrollkästchen gebunden blanke Saiten:in Knockout.js

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

Bis jetzt bin ich eine beobachtbare Array mit der Wahr/Falsch zu lösen Wert der Checkbox auf den Wert, ich brauche:

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

Welches ist die einfachste und schnellste Weg ist, wenn es eine gibt, ist ohne die Notwendigkeit, eine Checkbox in einen String-Wert zu binden als itemValue[0] zu verweisen?

Was ich brauche, ist der String-Wert, wenn markiert, Null, wenn nicht markiert.

Aufgrund der großen Menge an Observablen in meinem Viewmodel, ich würde vermeiden Tonnen Bedingungen zu verwenden, wie if(itemValue) ...

Fiddle mit einem observableArray: https://jsfiddle.net/wu470qup/

Antwort

0

Wenn Sie mühelos Markup möchten, müssen Sie müssen Verfolgen Sie die Kontrollkästchen, die Sie in Ihrem Ansichtsmodell darstellen möchten. Hier ist das einfachste Beispiel:

allValues ist eine regelmäßige Reihe von Zeichenfolgen. Jeder dieser Strings erhält ein Kontrollkästchen. itemValues ist ein beobachtbares Array der Strings, die ein Kontrollkästchen haben. correctedValues ist ein berechnetes Array mit null für jede nicht markierte Box und eine Zeichenfolge für jede überprüfte Box.

Beachten Sie, dass ich $data verwende im foreach den aktuellen String-Wert zu beziehen.

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>

Ein eleganter Ansatz wäre Viewmodels für jedes Kontrollkästchen zu erstellen. Zum Beispiel:

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

Mit dem HTML-Template:

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

Dann in dem übergeordneten Ansichtsmodell, können Sie eine beobachtbare Anordnung von CheckBoxItem s speichern und eine berechneten Array, das alle id Eigenschaften besitzt.

+0

Ich schätze Ihre Hilfe, wirklich, aber mein Viewmodel ist tief verschachtelt und außerdem gibt es ca. ~ 80 Komponenten - so ist in meiner Situation Ihr Vorschlag einer flachen Definition der Werte nicht wünschenswert. Ich suche eine minimalistische Lösung mit weniger Code & Blähungen als möglich. – deblocker

+0

Hmm Ich glaube nicht, dass ich deinen Anwendungsfall wirklich verstehe. Etwas mehr so? https://jsfiddle.net/ro2zn0hp/ – user3297291

+0

Etwas, dass mein vm JSON-Export aussieht wie {"itemValue": "CODE"} und nicht {"itemValue": ["CODE"]} und ich kann es als itemValue und nicht verweisen itemValue [0] - denke einfach wie ein Eingabetyp = Radio, ohne dass zwei Optionen angezeigt werden müssen – deblocker