Bagaimana cara membuat template struktur If-Else dalam tampilan terikat data?


95

Saya terus-menerus menemukan diri saya menggunakan idiom ini dalam template HTML berbasis 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 -->

Apakah ada cara yang lebih baik / lebih bersih untuk melakukan kondisional dalam KO, atau adakah pendekatan yang lebih baik daripada hanya menggunakan konstruksi if-else tradisional?

Selain itu, saya hanya ingin menunjukkan bahwa beberapa versi Internet Explorer (IE 8/9) tidak mengurai contoh di atas dengan benar. Silakan lihat pertanyaan SO ini untuk informasi lebih lanjut. Ringkasan singkatnya adalah, jangan gunakan komentar (pengikatan virtual) di dalam tag tabel untuk mendukung IE. Gunakan sebagai tbodygantinya:

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

Siapa pun yang melihat ini mungkin ingin melacak github.com/knockout/knockout/issues/962
Brian M. Hunt

Jawaban:


64

Ada beberapa cara berbeda untuk menangani jenis kode ini.

  • dengan kombinasi if / ifnot seperti Anda sekarang. Ini bekerja dengan baik dan tidak terlalu bertele-tele.

  • Switch / case binding Michael Best ( https://github.com/mbest/knockout-switch-case ) cukup fleksibel dan memungkinkan Anda menangani hal ini dengan mudah dan yang lebih rumit (lebih banyak status daripada true / false).

  • Pilihan lainnya adalah menggunakan template dinamis. Anda akan mengikat suatu area ke satu atau lebih templat dengan nama templat yang digunakan berdasarkan observasi. Berikut adalah posting yang saya tulis tentang topik ini beberapa waktu lalu: http://www.knockmeout.net/2011/03/quick-tip-dynamically-changing.html . Dalam skenario Anda, mungkin terlihat seperti:

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

The getCellTemplateFungsi bisa hidup di mana pun, tapi akan diberikan item ($ data) sebagai argumen pertama dan akan kembali nama template untuk digunakan.


aneh, HTML saya tidak akan muncul. Juga memperhatikan bahwa Michael memberikan jawaban yang kurang lebih sama.
RP Niemeyer

Terima kasih untuk daftar pilihan yang lengkap. Saya kira gaya kode asli saya berfungsi untuk kasus sederhana. Saya akan memeriksa opsi lain saat diperlukan.
Jensen Ching

apakah ada cara untuk menyesuaikan template lebih lanjut, seperti "template: data, proppertyName: 'email'" dan di template data-bind = "text: $ data [propertyName]".
Onur Topal

@OnurTOPAL - ya selama Anda memiliki variabel propertyName, Anda dapat menentukan nama template secara dinamis.
RP Niemeyer

44

Salah satu pendekatannya adalah dengan menggunakan template bernama (yang dapat mendukung penerusan argumen):

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

Opsi lainnya adalah menggunakan plugin switch / case saya , yang akan berfungsi seperti ini:

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

Terima kasih. Saya akan mengingat plugin sakelar / casing saat dibutuhkan.
Jensen Ching

2
Plugin bagus yang Anda dapatkan di sana! Akan menggunakan yang ini pasti.
Kukks

Template bernama berfungsi dengan baik, dan mendukung skenario tipe if elseif elseif else dengan menumpuk operator terniary.

4

Untuk menghindari penghitungan ulang pengikatan sistem gugur saat menggunakan kombinasi if: / ifnot: Anda dapat menggunakannya dalam hubungannya dengan konstruksi 'with:'

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

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.