wake-up-neo.net

Wie erstelle ich If-Else-Strukturen in datengebundenen Ansichten?

Ich verwende dieses Idiom ständig in KO-basierten HTML-Vorlagen:

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

Gibt es eine bessere/sauberere Möglichkeit, Bedingungen in KO zu erstellen, oder gibt es einen besseren Ansatz als nur herkömmliche if-else-Konstrukte?

Außerdem möchte ich darauf hinweisen, dass einige Versionen von Internet Explorer (IE 8/9) das obige Beispiel nicht korrekt analysieren. Weitere Informationen finden Sie unter this SO question . Die kurze Zusammenfassung lautet: Verwenden Sie keine Kommentare (virtuelle Bindungen) in Tabellen-Tags, um den IE zu unterstützen. Verwenden Sie tbody stattdessen:

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

Es gibt verschiedene Möglichkeiten, mit dieser Art von Code umzugehen.

  • mit einer If/Ifnot-Kombination wie jetzt. Dies funktioniert gut und ist nicht sehr ausführlich.

  • Die Schalter-/Fallbindung von Michael Best ( https://github.com/mbest/knockout-switch-case ) ist sehr flexibel und ermöglicht Ihnen die einfache Handhabung dieser und komplizierterer Zustände (mehr Zustände als wahr). falsch).

  • Eine weitere Option ist die Verwendung dynamischer Vorlagen. Sie würden einen Bereich an eine oder mehrere Vorlagen binden, wobei der Vorlagenname auf einer beobachtbaren Größe basiert. Hier ist ein Beitrag, den ich vor einiger Zeit zu diesem Thema geschrieben habe: http://www.knockmeout.net/2011/03/quick-tip-dynamically-changing.html . In Ihrem Szenario könnte es so aussehen:

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

Die getCellTemplate -Funktion kann überall verwendet werden, erhält jedoch das Element ($ data) als erstes Argument und gibt den Namen der zu verwendenden Vorlage zurück.

62
RP Niemeyer

Ein Ansatz ist die Verwendung benannter Vorlagen (die die Übergabe von Argumenten unterstützen können):

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

Eine andere Option ist die Verwendung von my switch/case plugin , die folgendermaßen funktionieren würde:

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

Um eine Neuberechnung der Knockout-Bindung zu vermeiden, wenn eine Kombination von if:/ifnot: verwendet wird, können Sie diese in Verbindung mit der 'with :'-Konstruktion verwenden

    <!-- ko with: $data.DoSomePerformanceCriticalWork($data.SomeParameter()) -->
        <!-- ko if: $data.Condition() -->
           ... some markup ...
        <!-- /ko -->
        <!-- ko ifnot: $data.Condition() -->
           ... some markup ...
        <!-- /ko -->
    <!-- /ko -->
4
Dmitry Komin

Es gibt jetzt auch die knockout-else binding/plugin (das ich geschrieben habe, um dieses Problem zu beheben).

1
Brian M. Hunt