Ciągle używam tego idiomu w szablonach HTML opartych na 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 -->
Czy istnieje lepszy / czystszy sposób wykonywania warunków warunkowych w KO, czy też istnieje lepsze podejście niż zwykłe używanie tradycyjnych konstrukcji if-else?
Chciałbym również zaznaczyć, że niektóre wersje przeglądarki Internet Explorer (IE 8/9) nie analizują poprawnie powyższego przykładu. Aby uzyskać więcej informacji, zobacz to pytanie SO . Krótkie podsumowanie brzmi: nie używaj komentarzy (wirtualnych powiązań) wewnątrz tagów tabeli do obsługi IE. Użyj tbody
zamiast tego:
<tbody data-bind="if: display"><tr><td>hello</td></tr></tbody>
javascript
knockout.js
Jensen Ching
źródło
źródło
Odpowiedzi:
Istnieje kilka różnych sposobów obsługi tego typu kodu.
z kombinacją if / ifnot, tak jak teraz. To działa dobrze i nie jest strasznie rozwlekłe.
Wiązanie przełącznika / wielkości liter Michaela Besta ( https://github.com/mbest/knockout-switch-case ) jest dość elastyczne i pozwala łatwo obsłużyć to i bardziej skomplikowane (więcej stanów niż prawda / fałsz).
Inną opcją jest użycie szablonów dynamicznych. Powiążesz obszar z jednym lub wieloma szablonami, używając nazwy szablonu opartej na obserwowalnym. Oto post, który napisałem na ten temat jakiś czas temu: http://www.knockmeout.net/2011/03/quick-tip-dynamically-changing.html . W Twoim scenariuszu może to wyglądać tak:
<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>
getCellTemplate
Funkcja może żyć wszędzie, ale byłby określony element ($ dane) jako pierwszy argument i zwróci nazwę szablonu do użytku.źródło
propertyName
, możesz dynamicznie określić nazwę szablonu.Jedną z metod jest użycie nazwanych szablonów (które mogą obsługiwać przekazywanie argumentów):
<!-- 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>
Inną opcją jest użycie mojej wtyczki switch / case , która działałaby tak:
<!-- 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 -->
źródło
Aby uniknąć ponownego obliczania wiązania typu knockout przy użyciu kombinacji if: / ifnot: możesz ich używać w połączeniu z konstrukcją „with:”
<!-- ko with: $data.DoSomePerformanceCriticalWork($data.SomeParameter()) --> <!-- ko if: $data.Condition() --> ... some markup ... <!-- /ko --> <!-- ko ifnot: $data.Condition() --> ... some markup ... <!-- /ko --> <!-- /ko -->
źródło
Jest teraz również
knockout-else
powiązanie / wtyczka (którą napisałem, aby rozwiązać ten problem).źródło