2012-07-19 4 views
92

ho sempre trovo con questo idioma in modelli HTML KO-based:Come modellare le strutture If-Else nelle viste con associazione a dati?

<!-- ko if: isEdit --> 
<td><input type="text" name="email" data-bind="value: email" /></td> 
<!-- /ko --> 
<!-- ko ifnot: isEdit --> 
<td data-bind="text: email"></td> 
<!-- /ko --> 

Esiste un/modo migliore più pulito di fare condizionali in KO, o c'è una migliore approccio non solo con i tradizionali if-else costruisce?

Inoltre, vorrei solo sottolineare che alcune versioni di Internet Explorer (IE 8/9) non analizzano correttamente l'esempio precedente. Si prega di consultare this SO question per ulteriori informazioni. Il riepilogo rapido è, non utilizzare commenti (binding virtuali) all'interno dei tag tabella per supportare IE. Utilizzare il tbody invece:

<tbody data-bind="if: display"><tr><td>hello</td></tr></tbody> 
+0

Chiunque guardi questo potrebbe voler tenere traccia di https://github.com/knockout/knockout/issues/962 –

risposta

62

Ci sono un paio di modi diversi per gestire questo tipo di codice.

  • con una combinazione if/ifnot come ora. Funziona bene e non è terribilmente prolisso.

  • Michael Best's binding/case binding (https://github.com/mbest/knockout-switch-case) è abbastanza flessibile e consente di gestire facilmente questo e altri più complicati (più stati che vero/falso).

  • Un'altra opzione è utilizzare modelli dinamici. Dovresti associare un'area a uno o più modelli con il nome del modello utilizzato in base a un osservabile. Ecco un post che ho scritto su questo argomento qualche tempo fa: http://www.knockmeout.net/2011/03/quick-tip-dynamically-changing.html. Nel vostro scenario, potrebbe assomigliare:

<td data-bind="template: $root.getCellTemplate"></td> 

<script id="cellEditTmpl" type="text/html"> 
    <input type="text" name="email" data-bind="value: email" /> 
</script> 

<script id="cellTmpl" type="text/html"> 
    <span data-bind="text: email"></span> 
</script> 

La funzione getCellTemplate poteva vivere ovunque, ma sarebbe stata data la voce ($ dati) come primo argomento e sarebbe tornato il nome del modello da utilizzare .

+0

strano, il mio codice HTML non verrà visualizzato. Inoltre ho appena notato che Michael ha dato più o meno la stessa risposta. –

+0

Grazie per un elenco completo di opzioni. Immagino che il mio stile di codice originale funzioni per casi semplici. Controllerò le altre opzioni quando si presenterà la necessità. –

+0

c'è un modo per personalizzare ulteriormente il modello, come "template: data, proppertyName: 'email'" e nel template data-bind = "text: $ data [propertyName]". –

40

Un approccio è quello di utilizzare modelli definiti (in grado di supportare il passaggio di argomenti):

<!-- ko template: isEdit() ? 'emailEdit' : 'emailDisplay' --><!-- /ko --> 
<script id="emailEdit" type="text/html"> 
    <td><input type="text" name="email" data-bind="value: email" /></td> 
</script> 
<script id="emailDisplay" type="text/html"> 
    <td data-bind="text: email"></td> 
</script> 

Un'altra opzione è utilizzare il mio switch/case plugin, che avrebbe funzionato in questo modo:

<!-- ko switch --> 
    <!-- ko case: isEdit --> 
     <td><input type="text" name="email" data-bind="value: email" /></td> 
    <!-- /ko --> 
    <!-- ko case: $else --> 
     <td data-bind="text: email"></td> 
    <!-- /ko --> 
<!-- /ko --> 
+0

Grazie. Terrò in considerazione il plug-in switch/case per quando è necessario. –

+2

Bel plugin che hai ottenuto! Userò questo di sicuro. – Kukks

+0

I modelli denominati funzionano in modo ottimale e supportano se elseif elseif altri tipi di scenari annidando l'operatore terniario. – Will

4

Per evitare il ricalcolo di eliminazione diretta vincolante quando si utilizza combinazione di caso:/ifnot: si possono usare in combinazione con 'con:' costruzione

<!-- ko with: $data.DoSomePerformanceCriticalWork($data.SomeParameter()) --> 
     <!-- ko if: $data.Condition() --> 
      ... some markup ... 
     <!-- /ko --> 
     <!-- ko ifnot: $data.Condition() --> 
      ... some markup ... 
     <!-- /ko --> 
    <!-- /ko --> 
1

V'è ora anche il knockout-else vincolante/plugin (che ho ha scritto per risolvere questo problema).