Comment modéliser des structures If-Else dans des vues liées aux données?


95

Je me retrouve constamment à utiliser cet idiome dans des modèles HTML basés sur 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 -->

Existe-t-il un moyen meilleur / plus propre de faire des conditions dans KO, ou y a-t-il une meilleure approche que d'utiliser simplement des constructions if-else traditionnelles?

De plus, je voudrais juste souligner que certaines versions d'Internet Explorer (IE 8/9) n'analysent pas correctement l'exemple ci-dessus. Veuillez consulter cette question SO pour plus d'informations. Le résumé rapide est de ne pas utiliser de commentaires (liaisons virtuelles) à l'intérieur des balises de table pour prendre en charge IE. Utilisez tbodyplutôt le:

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

Quiconque regarde cela peut souhaiter suivre github.com/knockout/knockout/issues/962
Brian M. Hunt

Réponses:


64

Il existe plusieurs manières de gérer ce type de code.

  • avec une combinaison if / ifnot comme vous l'êtes maintenant. Cela fonctionne très bien et n'est pas terriblement verbeux.

  • La liaison switch / case de Michael Best ( https://github.com/mbest/knockout-switch-case ) est assez flexible et peut vous permettre de gérer facilement cela et les plus compliqués (plus d'états que true / false).

  • Une autre option consiste à utiliser des modèles dynamiques. Vous lieriez une zone à un ou plusieurs modèles avec le nom du modèle utilisé en fonction d'un observable. Voici un article que j'ai écrit sur ce sujet il y a quelque temps: http://www.knockmeout.net/2011/03/quick-tip-dynamically-changing.html . Dans votre scénario, cela pourrait ressembler à:

<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 getCellTemplatefonction pourrait vivre n'importe où, mais recevrait l'élément ($ data) comme premier argument et renverrait le nom du modèle à utiliser.


étrange, mon HTML n'apparaîtra pas. Je viens également de remarquer que Michael a donné à peu près la même réponse.
RP Niemeyer

Merci pour une liste complète d'options. Je suppose que mon style de code original fonctionne pour des cas simples. Je vérifierai les autres options lorsque le besoin se fera sentir.
Jensen Ching

existe-t-il un moyen de personnaliser encore plus le modèle, comme "template: data, proppertyName: 'email'" et dans le template data-bind = "text: $ data [propertyName]".
Onur Topal

@OnurTOPAL - oui tant que vous avez une variable propertyName, vous pouvez déterminer dynamiquement le nom du modèle.
RP Niemeyer

44

Une approche consiste à utiliser des modèles nommés (qui peuvent prendre en charge le passage d'arguments):

<!-- 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>

Une autre option est d'utiliser mon plugin switch / case , qui fonctionnerait comme ceci:

<!-- 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 -->

Merci. Je garderai à l'esprit le plugin switch / case en cas de besoin.
Jensen Ching

2
Beau plugin vous y êtes! J'utilisera celui-ci à coup sûr.
Kukks

Les modèles nommés fonctionnent très bien et prennent en charge les scénarios de type if elseif elseif else en imbriquant l'opérateur terniaire.

4

Pour éviter de recalculer la liaison knockout lors de l'utilisation de la combinaison de if: / ifnot: vous pouvez les utiliser en conjonction avec la construction 'with:'

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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.