Come modellare le strutture If-Else nelle viste con associazione a dati?


95

Mi trovo costantemente a usare questo idioma nei modelli HTML basati su KO:

<!-- 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 per eseguire i condizionali in KO, o esiste un approccio migliore rispetto all'uso dei tradizionali costrutti if-else?

Inoltre, vorrei solo sottolineare che alcune versioni di Internet Explorer (IE 8/9) non analizzano correttamente l'esempio precedente. Si prega di consultare questa domanda SO per ulteriori informazioni. Il breve riepilogo è: non utilizzare commenti (associazioni virtuali) all'interno dei tag della tabella per supportare IE. Usa tbodyinvece:

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

Chiunque guardi questo potrebbe voler monitorare github.com/knockout/knockout/issues/962
Brian M. Hunt,

Risposte:


64

Esistono un paio di modi diversi per gestire questo tipo di codice.

  • con una combinazione if / ifnot come sei adesso. Funziona bene e non è particolarmente prolisso.

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

  • Un'altra opzione è utilizzare modelli dinamici. Assoceresti 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 tuo scenario, potrebbe apparire come:

<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 getCellTemplatefunzione potrebbe vivere ovunque, ma riceverebbe l'elemento ($ data) come primo argomento e restituirebbe il nome del modello da utilizzare.


strano, il mio HTML non verrà visualizzato. Ho anche notato che Michael ha dato più o meno la stessa risposta.
RP Niemeyer

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

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

@OnurTOPAL - sì, finché hai una variabile propertyName, puoi determinare dinamicamente il nome del modello.
RP Niemeyer

44

Un approccio consiste nell'usare modelli denominati (che possono 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 plug-in switch / case , che funzionerebbe 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 -->

Grazie. Terrò a mente il plug-in switch / case per quando se ne presenta la necessità.
Jensen Ching

2
Bel plugin che hai! Lo userò di sicuro.
Kukks

I modelli denominati funzionano alla grande e supportano scenari di tipo if elseif elseif else annidando l'operatore terziario.

4

Per evitare il ricalcolo dell'associazione knockout quando si utilizza la combinazione di if: / ifnot: è possibile utilizzarli insieme alla costruzione 'with:'

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.