web-dev-qa-db-fra.com

Comment modéliser des structures If-Else dans des vues liées aux 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 une meilleure façon/plus propre de faire des conditionnelles dans KO, ou existe-t-il une meilleure approche que de simplement utiliser les constructions traditionnelles if-else?

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 this SO question pour plus d'informations. Pour résumer, n'utilisez pas de commentaires (liaisons virtuelles) dans les balises de table pour prendre en charge IE. Utilisez la fonction tbody à la place:

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

Vous pouvez gérer ce type de code de deux manières différentes.

  • avec une combinaison si/si pas comme vous êtes maintenant. Cela fonctionne bien et n'est pas terriblement prolixe.

  • La liaison commutateur/cas de Michael Best ( https://github.com/mbest/knockout-switch-case ) est assez flexible et peut vous permettre de gérer facilement cela et d'autres plus compliquées (plus d'états que vrais/faux).

  • Une autre option consiste à utiliser des modèles dynamiques. Vous lieriez 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>

La fonction getCellTemplate pourrait vivre n'importe où, mais le premier argument serait donné à l'élément ($ data) et renverrait le nom du modèle à utiliser.

62
RP Niemeyer

Une approche consiste à utiliser des modèles nommés (qui peuvent supporter les arguments de passage):

<!-- 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 -->
43
Michael Best

Pour éviter de recalculer la reliure knock-out lors de l'utilisation de la combinaison if:/ifnot: vous pouvez les utiliser conjointement 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 -->
4
Dmitry Komin

Il y a maintenant aussi le knockout-else binding/plugin (que j'ai écrit pour résoudre ce problème).

1
Brian M. Hunt