Bagaimana cara berbagi Knockout JS yang dapat diamati antara Komponen UI


12

Saya mengerti cara menggunakan imports: {}danexports: {} berbagi properti komponen UI, seperti:

defaults: {
    exports: {
        shouldShowMessage: '${$.component}'
    }
}

Yang mengembalikan nama komponen dalam ekspor.

masukkan deskripsi gambar di sini

Tetapi ketika saya mencoba mengekspor Knockout yang dapat diamati, selalu tidak terdefinisi:

defaults: {
    exports: {
        shouldShowMessage: '${$.shouldShowMessage}'
    }
}

...

setupKoBindings: function() {
    this.shouldShowMessage = ko.observable('Testing');
}

masukkan deskripsi gambar di sini

Sebagai solusinya saya akan membuat model penyimpanan seperti yang dijelaskan di sini, tetapi saya lebih suka menggunakan impor dan ekspor.

Jawaban:


12

Nilai-nilai objek ekspor harus menyelesaikan ke nama dan properti instance UiComponent, dipisahkan oleh ':', misalnya checkout.cart.total:title.
Nama target ekspor harus menyertakan komponen UI "namespace".

Dalam contoh Anda, Anda menetapkan nilai ke string, yang memutuskan ke properti UiComponent yang merupakan sumber ekspor. Ekspor tidak terdefinisi saat Anda memeriksanya karena itu bukan target ekspor yang valid.

Berikut ini contoh yang berfungsi:

defaults: {
    exportTarget: "foo.bar",
    exportTargetProperty: "showMessage",

    tracks: {
        shouldShowMessage: true
    },

    exports: {
        shouldShowMessage: '${$.exportTarget}:${$.exportTargetProperty}'
    }
}
...

Di atas akan menyalin nilai shouldShowMessageproperti ke properti showMessageUiComponent dengan nama lengkap foo.barsetiap kali nilainya berubah.
Perhatikan bahwa ini tidak akan secara otomatis menjadikan properti target KO juga dapat diamati. Itu harus dinyatakan secara eksplisit, jika perubahan nilai harus memicu KO ke rerender DOM node yang mengakses properti itu.

By the way, menambahkan shouldShowMessageke tracksobjek akan membuatnya menjadi ko-ES5 diamati otomatis. Menggunakan ko.observable()karya literal juga.

Pada contoh di atas, exportTargetdan exportTargetPropertydikonfigurasikan di defaults. Mereka juga dapat ditentukan sebagai bagian dari opsi UiComponent di JSON, yang biasanya lebih masuk akal, karena di situlah hierarki UiComponent termasuk nama-nama UiComponent didefinisikan.

Akhirnya, saya ingin mencatat bahwa saya pribadi berpikir solusi Anda menggunakan objek nilai untuk meneruskan nilai ke komponen UI lainnya lebih baik daripada menggunakan ekspor atau impor. Dalam pengalaman saya menjaga keadaan bersama di DOM atau di UiComponents adalah resep untuk spaghetti OOP dalam semua kasus kecuali yang paling sederhana.


Penjelasan yang bagus, terima kasih @Vinai! Saya akan mencobanya ketika saya punya waktu dan menandainya sebagai diterima jika berfungsi.
Ben Crook

Saya telah mengalami beberapa masalah saat menggunakan tracks, berlangganan secara manual ke yang dapat diobservasi tidak lagi berfungsi this.shouldShowMessage.subscribe is not a functionsaat menggunakannya this.shouldShowMessage.subscribe(function() { ... }); Ini berfungsi dengan baik saat mengatur yang dapat diamati dengan cara lain. Terasa seolah-olah saya kehilangan langkah atau trackstidak menciptakan cara yang bisa diamati.
Ben Crook

Anda benar, sifat-sifat tidak lagi biasa diamati, hanya ES5 pengambil / pasangan setter. Jika Anda ingin mengakses fungsi asli yang dapat diamati, Anda dapat menyuntikkan ko dan menggunakan ko.getObservable(this, 'shouldShowMessage').subscribe(function(newValue) { ...});(argumen pertama adalah viewmodel ( this), yang kedua adalah nama properti yang dilacak. Info lebih lanjut di sini: github.com/SteveSanderson/knockout-es5
Vinai

Ahh itu masuk akal, Anda yang terbaik <3
Ben Crook

1
Setelah bermain-main dengan impor dan ekspor dan masih gagal saya setuju ini adalah kode spaghetti, saya sudah menyerah dan saya akan tetap dengan langganan manual dan model penyimpanan.
Ben Crook
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.