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