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.