2012-01-19 13 views
10

Vorrei scorrere un array che definisco nel mio Javascript e rendere un elenco di pulsanti di opzione. Il mio codice che non funziona attualmente, ed è la seguente (anche su jsfiddle):Come eseguire il rendering di un array come elenco di pulsanti di opzione?

<div data-bind="foreach: options" > 
    <div> 
     <input type="radio" name="optionsGroup" data-bind="checked: selected" /> 
     <span data-bind="text: label"></span> 
    </div>  
</div> 
var optionsList = [ 
    {"value": "a","label": "apple"}, 
    {"value": "b","label": "banana"}, 
    {"value": "c","label": "carrot"} 
]; 
function viewModel() { 
    var self = this; 
    self.options = optionsList; 
    self.selected = ko.observable("a"); 
    self.selected.subscribe(function(newValue) { 
     alert("new value is " + newValue); 
    }); 
} 
ko.applyBindings(new viewModel()); 

Se il mio array è parte del codice HTML, allora funziona benissimo, vedere questo (o jsfiddle):

<div> 
    <input type="radio" name="optionsGroup" value="a" data-bind="checked: selected"  />Apple 
</div> 
<div> 
    <input type="radio" name="optionsGroup" value="b" data-bind="checked: selected" />Banana 
</div> 
<div> 
    <input type="radio" name="optionsGroup" value="c" data-bind="checked: selected" />Carrot 
</div> 
<div data-bind="text: selected"> 
</div> 
function viewModel() { 
    var self = this; 
    self.selected = ko.observable("a"); 
    self.selected.subscribe(function(newValue) { 
     alert("new value is " + newValue); 
    }); 
}  
ko.applyBindings(new viewModel()); 

ho ottenuto questo al lavoro generando il tutto il codice HTML nei miei javascript e hanno questo utilizzando le caselle di controllo di lavoro, ma stumped generare un gruppo di radiobutton utilizzando l'iterato foreach r.

Qualcuno ha avuto un esempio come il mio primo a lavorare?

+1

Sicuramente puoi trovare un titolo più informativo. –

+0

Vale la pena notare che non hai bisogno di 'var self = this' nel tuo viewModel. Elimina quella linea e cambia tutto 'self's in' this'. Scope sta bene senza. – ruffin

risposta

1

Il codice sta dando questo errore:

Message: ReferenceError: selected is not defined;

Bindings value: checked: selected

È definito selected sul piano vista del modello, ma si fa riferimento all'interno foreach così Knockout.js è alla ricerca di esso a livello opzioni.

Cambio:

<div><input type="radio" name="optionsGroup" data-bind="checked: selected" /> 

a:

<div><input type="radio" name="optionsGroup" data-bind="checked: $root.selected" /> 

$root.selected cercherà la proprietà selected sul piano vista del modello.

HERE è il codice modificato.

Per ulteriori informazioni sulle pseudo-variabili (come $root), vedere 3. Access to parent binding contexts.

+0

Grazie dzejkej. Questo è molto apprezzato. Studierò il collegamento. – user759608

16

Ecco un modo per farlo. Si noti che l'associazione attr deve essere preceduta dall'associazione checked.

var optionsList = [ 
 
    {"value": "a", "label": "apple"}, 
 
    {"value": "b", "label": "banana"}, 
 
    {"value": "c", "label": "carrot"} 
 
]; 
 

 
function viewModel() { 
 
    this.options = optionsList; 
 
    this.selected = ko.observable("a"); 
 
} 
 

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

 
<h3>Fruits</h3> 
 
<div data-bind="foreach: options" > 
 
    <label> 
 
    <input type="radio" 
 
      name="optionsGroup" 
 
      data-bind="attr: {value: value}, checked: $root.selected" /> 
 
    <span data-bind="text: label"></span> 
 
    </label>  
 
</div> 
 

 
<h3>Selected value:</h3> 
 
<pre data-bind="text: ko.toJSON($root.selected)"></pre>

+5

Il mio problema era l'associazione 'attr' che non veniva prima controllata. Ha senso ma non sembra subito. – kamranicus

+0

[Fiddle of above answer in context] (http://jsfiddle.net/rufwork/7c5kk/) (solo per i calci). – ruffin

+0

Nelle versioni di Knockout recenti, $ root è diventato $ padre –

1

Per essere in grado di avere l'intero oggetto è meglio usare CheckedValue invece di attr: {valore} così:

Fruits 
<div data-bind="foreach: options" > 
    <div><input type="radio" name="optionsGroup" data-bind="checkedValue: $data, checked: $root.selected" /> 
    <span data-bind="text: label"></span></div>  
</div>