94 votes

Comment créer des structures If-Else dans des vues liées à des données ?

Je me retrouve constamment à utiliser cet idiome dans les 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 plus efficace et plus propre de faire des conditionnels dans KO, ou existe-t-il un meilleur moyen de faire des conditionnels dans KO ? approche que d'utiliser les constructions traditionnelles if-else ?

Je tiens également à signaler 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. En résumé, n'utilisez pas de commentaires (liaisons virtuelles) à l'intérieur des balises de tableau pour prendre en charge IE. Utilisez la balise tbody à la place :

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

63voto

RP Niemeyer Points 81663

Vous pouvez traiter ce type de code de plusieurs manières différentes.

  • avec une combinaison if/ifnot comme vous le faites maintenant. Cela fonctionne bien et n'est pas terriblement verbeux.

  • La liaison interrupteur/case de Michael Best ( https://github.com/mbest/knockout-switch-case ) est assez souple et peut vous permettre de gérer facilement ce type de question et d'autres plus complexes (plus d'états que vrai/faux).

  • Une autre option consiste à utiliser des modèles dynamiques. Vous liez une zone à un ou plusieurs modèles, le nom du modèle étant 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>

El getCellTemplate peut être placée n'importe où, mais elle reçoit l'élément ($data) comme premier argument et renvoie le nom du modèle à utiliser.

44voto

Michael Best Points 9033

Une approche consiste à utiliser des modèles nommés (qui peuvent supporter 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 consiste à utiliser mon plugin switch/case qui fonctionnerait de la manière suivante :

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

4voto

Dmitry Komin Points 11

Pour éviter de recalculer la liaison knockout lors de l'utilisation d'une 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 -->

1voto

Brian M. Hunt Points 12506

Il existe désormais aussi le knockout-else (que j'ai écrit pour résoudre ce problème).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X