Jak szablonować struktury If-Else w widokach powiązanych z danymi?


95

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 tbodyzamiast tego:

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

Każdy, kto na to spojrzy,
— Brian M. Hunt

Odpowiedzi:


64

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>

getCellTemplateFunkcja może żyć wszędzie, ale byłby określony element ($ dane) jako pierwszy argument i zwróci nazwę szablonu do użytku.


dziwne, mój kod HTML się nie wyświetla. Właśnie zauważyłem, że Michael udzielił prawie takiej samej odpowiedzi.
— RP Niemeyer,

Dzięki za wyczerpującą listę opcji. Myślę, że mój oryginalny styl kodu działa w prostych przypadkach. W razie potrzeby sprawdzę inne opcje.
— Jensen Ching,

czy istnieje sposób na jeszcze większe dostosowanie szablonu, na przykład „template: data, proppertyName: 'email'” oraz w szablonie data-bind = "text: $ data [propertyName]".
— Onur Topal

@OnurTOPAL - tak, o ile masz zmienną propertyName, możesz dynamicznie określić nazwę szablonu.
— RP Niemeyer

44

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

Dzięki. Będę pamiętać o wtyczce przełącznika / obudowy, gdy zajdzie taka potrzeba.
— Jensen Ching,

2
Dobra wtyczka, którą masz! Na pewno skorzystam z tego.
— Kukks

Nazwane szablony działają świetnie i obsługują scenariusze typu if elseif elseif else przez zagnieżdżanie operatora terniary.

4

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.