2013-12-16 15 views
5

Sto cercando di utilizzare l'associazione checkedValue introdotta nella versione 3 ad eliminazione diretta, con i pulsanti di opzione, ma non sto ottenendo il comportamento che mi aspetto.Uso dell'associazione checkedValue con i pulsanti di opzione

Ecco un esempio: (viewmodel ha due proprietà; list è un array; checkedVal è un'osservabile)

<div data-bind="foreach:list"> 
    <input type="radio" data-bind=" 
     checkedValue: { 
      data: $data, 
      index: $index(), 
     }, 
     checked: $parent.checkedVal 
    "/> 
    <span data-bind="text: $data"></span> 
</div> 

JSFiddle

mi aspetto che i pulsanti di opzione per comportarsi normalmente e checkedVal essere un oggetto contenente i dati e l'indice. checkedVal è come mi aspetto, ma i pulsanti di opzione non selezionano. Stranamente, nel mio codice attuale il comportamento è incoerente; a volte la radio funziona ma a volte no, ma costantemente non funziona nel violino, per quanto posso vedere.

Si tratta di un errore o non capisco come dovrebbe funzionare?

risposta

0

Sembra che questo problema è stato risolto in versioni più recenti di KO. A partire dalla versione 3.2, non vedo più questo comportamento menzionato nella mia domanda originale.

Ecco uno working JSFiddle, identico all'originale, tranne con KO aggiornato a 3.2.

1

tuo checkedValue vincolante diventa una funzione come segue:

function() { 
    return { 
     data: $data, 
     index: $index(), 
    }; 
} 

Ogni volta che i checked aggiornamenti vincolanti, si chiama questa funzione per ottenere il valore. Ma la funzione restituisce sempre un nuovo oggetto. Anche se gli oggetti contengono gli stessi dati, Knockout non li vede come gli stessi.

È possibile risolvere questo rendendo il valore una stringa.

<input type="radio" data-bind=" 
     checkedValue: JSON.stringify({ 
      data: $data, 
      index: $index(), 
     }), 
     checked: $parent.checkedVal 
    "/> 

O vincolante a un valore coerente.

<input type="radio" data-bind=" 
     checkedValue: $data, 
     checked: $parent.checkedVal 
    "/> 

EDIT:

È possibile utilizzare un costume vincolante che segue lo stesso schema checked, ma consente una funzione di confronto.

ko.bindingHandlers.radioChecked = { 
    init: function (element, valueAccessor, allBindings) { 
     ko.utils.registerEventHandler(element, "click", function() { 
      if (element.checked) { 
       var observable = valueAccessor(), 
        checkedValue = allBindings.get('checkedValue'); 
       observable(checkedValue); 
      } 
     }); 
    }, 
    update: function (element, valueAccessor, allBindings) { 
     var modelValue = valueAccessor()(), 
      checkedValue = allBindings.get('checkedValue'), 
      comparer = allBindings.get('checkedComparer'); 
     element.checked = comparer(modelValue, checkedValue); 
    } 
}; 

Quindi gli oggetti possono essere confrontati per contenuto.

this.itemCompare = function(a, b) { 
    return JSON.stringify(a) == JSON.stringify(b); 
} 

jsFiddle: http://jsfiddle.net/mbest/Q4LSQ/

+0

Se questo è vero, allora non vedo il punto di checkedValue; il primo esempio avrebbe certamente funzionato solo con "valore", e penso che anche il secondo sarebbe. – Retsam

+0

Potresti essere interessato al binding personalizzato che ho aggiunto che può essere usato al posto di 'checked' e supporta una funzione di confronto. –

Problemi correlati