2012-01-24 10 views
6

Sto tentando di impostare modelli di knockout generici che possono essere alternati tra modalità di modifica e di sola lettura in base al tipo di dati. Se hai mai usato i dati dinamici di ASP.NET: è come i loro modelli di campo. Per esempio:

<script type="text/html" id="text"> 
    <!-- ko if: $root.editable --> 
     <input type="text" data-bind="value: $data" /> 
    <!-- /ko --> 

    <!-- ko ifnot: $root.editable --> 
     <span data-bind="text: $data"></span> 
    <!-- /ko --> 
</script> 

Questo è usato in questo modo:

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

<p>Name: <input data-bind="value: name" /></p> 
<p>Name2: <span data-bind="template: { name: 'text', data: name }"></span></p> 

Con la seguente vista del modello:

var viewModel = { 
     name: ko.observable("Brian"), 
     editable: ko.observable(true) 
    }; 

L'idea è quella di essere in grado di utilizzare i modelli a livello di campo come nell'esempio "Nome2", invece di elementi/controlli espliciti. Ciò consente di alternare facilmente interi moduli tra la modalità di modifica e quella di lettura senza disporre di ampie sezioni di markup per lo più duplicati. Questo permette anche il riutilizzo dei comuni tipo di dati markup modifica/visualizzazione, ad esempio utilizzando datepickers per i campi data, ecc

Il problema
Il $data pseudo variabile all'interno del modello non ha legame bidirezionale. Riflette il valore corrente nell'osservabile, ma i cambiamenti nel controllo di input non imposteranno il valore.

Come posso ottenere un collegamento bidirezionale su $data?

Vedi anche this jsfiddle

risposta

7

La scelta più semplice è quello di passare un oggetto al modello vincolante che consente di accedere al osservabile attuale come:

template: { name: 'text', data: {field: name} } 

Poi, si legano contro il "campo" al posto di " $ dati "nel tuo modello.

Un'altra cosa da considerare sarebbe utilizzando una funzione per determinare il modello, quindi è possibile utilizzare i modelli separati per la modifica/visualizzazione come:
http://www.knockmeout.net/2011/03/quick-tip-dynamically-changing.html

+0

Grazie! Tu sei l'uomo Ryan! –

+0

Una domanda, forse qualcuno sa perché quando sto usando '$ data' e' $ item' keywords - il template non è renderizzato, ma quando si accede agli elementi passati in 'foreach' dai nomi dei campi ViewModel - tutto funziona bene, ad esempio ho legato viewModel con array di utenti (con un solo campo 'name'), quindi il binding a' name' funziona nel template, ma quando si usa '$ data' o' $ item' - non riesce a farlo funzionare. Per esempio '' non funziona ma '' va bene, quindi non riesco ad accedere '$ root, $ item, $ data' cosa potrebbe causare tale problema? Grazie – sll

+0

Forse potresti creare il tuo problema in un jsFiddle? '$ item' è disponibile solo in template jQuery. Se '$ data' è un oggetto, quindi non si vorrebbe passarlo al binding del testo, si vorrebbe fare' text: name' o 'text: $ data.name' (la seconda sintassi aiuta con undefined). –

Problemi correlati