Saya membangun fungsionalitas ke halaman web yang dapat dilakukan pengguna beberapa kali. Melalui tindakan pengguna, objek / model dibuat dan diterapkan ke HTML menggunakan ko.applyBindings ().
HTML terikat data dibuat melalui template jQuery.
Sejauh ini baik.
Ketika saya mengulangi langkah ini dengan membuat objek / model kedua dan memanggil ko.applyBindings () saya mengalami dua masalah:
- Markup menunjukkan objek / model sebelumnya serta objek / model baru.
- Terjadi kesalahan javascript terkait dengan salah satu properti dalam objek / model, meskipun masih dirender dalam markup.
Untuk mengatasi masalah ini, setelah lulus pertama saya memanggil jQuery's .empty () untuk menghapus HTML template yang berisi semua atribut data-bind, sehingga tidak lagi di DOM. Saat pengguna memulai proses untuk umpan kedua, HTML yang terikat data ditambahkan kembali ke DOM.
Tapi seperti yang saya katakan, ketika HTML ditambahkan kembali ke DOM dan diikat ulang ke objek / model baru, itu masih menyertakan data dari objek / model pertama, dan saya masih mendapatkan kesalahan JS yang tidak terjadi selama lintasan pertama.
Kesimpulannya adalah bahwa Knockout mempertahankan properti terikat ini, meskipun markup dihapus dari DOM.
Jadi yang saya cari adalah cara untuk menghapus properti terikat ini dari Knockout; memberi tahu knockout bahwa tidak ada lagi model yang dapat diamati. Apakah ada cara untuk melakukan ini?
EDIT
Proses dasarnya adalah pengguna mengunggah file; server kemudian merespons dengan objek JSON, HTML terikat data ditambahkan ke DOM, kemudian model objek JSON terikat ke HTML ini menggunakan
mn.AccountCreationModel = new AccountViewModel(jsonData.Account);
ko.applyBindings(mn.AccountCreationModel);
Setelah pengguna membuat beberapa pilihan pada model, objek yang sama dikirim kembali ke server, HTML yang terikat data dihapus dari DOM, dan saya kemudian memiliki JS berikut
mn.AccountCreationModel = null;
Ketika pengguna ingin melakukan ini sekali lagi, semua langkah ini diulangi.
Saya khawatir kodenya terlalu 'terlibat' untuk melakukan demo jsFiddle.
init
fungsi di mana Anda meneruskan data untuk diterapkan?Jawaban:
Sudahkah Anda mencoba memanggil metode simpul bersih knockout pada elemen DOM Anda untuk membuang objek yang terikat dalam memori?
Kemudian menerapkan pengikatan knockout lagi hanya pada elemen itu dengan model tampilan baru Anda akan memperbarui pengikatan tampilan Anda.
sumber
delete
kunci tertentu pada elemen dom itu sendiri, yang tampaknya di mana semua sihir sistem gugur disimpan. Jika ada yang punya sumber dokumentasi, saya akan sangat berterima kasih.Untuk proyek yang sedang saya kerjakan, saya menulis
ko.unapplyBindings
fungsi sederhana yang menerima node jQuery dan menghapus boolean. Ini pertama-tama melepaskan semua peristiwa jQuery karenako.cleanNode
metode tidak menangani itu. Saya telah menguji kebocoran memori, dan tampaknya berfungsi dengan baik.sumber
ko.cleanNode()
dipanggil dan tidak seluruh html diganti.Anda dapat mencoba menggunakan with binding yang menawarkan knockout: http://knockoutjs.com/documentation/with-binding.html Idenya adalah menggunakan apply binding satu kali, dan setiap kali data Anda berubah, perbarui saja model Anda.
Katakanlah Anda memiliki model tampilan storeViewModel tingkat atas, keranjang Anda diwakili oleh cartViewModel, dan daftar item di keranjang itu - misalnya cartItemsViewModel.
Anda akan mengikat model tingkat atas - storeViewModel ke seluruh halaman. Kemudian, Anda dapat memisahkan bagian halaman Anda yang bertanggung jawab atas item keranjang atau keranjang.
Mari kita asumsikan bahwa cartItemsViewModel memiliki struktur berikut:
CartItemsViewModel bisa kosong di awal.
Langkah-langkahnya akan terlihat seperti ini:
Tentukan binding di html. Pisahkan pengikatan cartItemsViewModel.
Model toko berasal dari server Anda (atau dibuat dengan cara lain).
var storeViewModel = ko.mapping.fromJS(modelFromServer)
Tentukan model kosong pada model tampilan tingkat atas Anda. Kemudian struktur model itu dapat diperbarui dengan data aktual.
Ikat model tampilan tingkat atas.
ko.applyBindings(storeViewModel);
Saat objek cartItemsViewModel tersedia, tetapkan ke placeholder yang ditentukan sebelumnya.
storeViewModel.cartItemsViewModel(actualCartItemsModel);
Jika Anda ingin menghapus item keranjang:
storeViewModel.cartItemsViewModel(null);
Knockout akan menangani html - yaitu akan muncul saat model tidak kosong dan konten div (yang memiliki "dengan pengikatan") akan hilang.
sumber
Saya harus memanggil ko.applyBinding setiap kali klik tombol pencarian, dan data yang difilter dikembalikan dari server, dan dalam hal ini mengikuti pekerjaan untuk saya tanpa menggunakan ko.cleanNode.
Saya mengalami, jika kita mengganti foreach dengan template maka itu akan berfungsi dengan baik dalam kasus collections / observableArray.
Anda mungkin menemukan skenario ini berguna.
sumber
Alih-alih menggunakan fungsi internal KO dan berurusan dengan penghapusan penanganan peristiwa selimut JQuery, ide yang jauh lebih baik adalah menggunakan
with
atautemplate
mengikat. Saat Anda melakukan ini, ko membuat ulang bagian DOM tersebut dan secara otomatis dibersihkan. Ini juga cara yang disarankan, lihat di sini: https://stackoverflow.com/a/15069509/207661 .sumber
Saya pikir mungkin lebih baik untuk tetap mengikat sepanjang waktu, dan cukup perbarui data yang terkait dengannya. Saya mengalami masalah ini, dan menemukan bahwa hanya memanggil menggunakan
.resetAll()
metode pada larik tempat saya menyimpan data adalah cara paling efektif untuk melakukan ini.Pada dasarnya Anda bisa memulai dengan beberapa var global yang berisi data yang akan dirender melalui ViewModel:
Butuh beberapa saat bagi saya untuk menyadari bahwa saya tidak bisa hanya membuat
myLiveData
array normal -ko.oberservableArray
bagian itu penting.Kemudian Anda dapat melanjutkan dan melakukan apa pun yang Anda inginkan
myLiveData
. Misalnya, lakukan$.getJSON
panggilan:Setelah Anda selesai melakukannya, Anda dapat melanjutkan dan menerapkan binding menggunakan ViewModel seperti biasa:
Kemudian di HTML gunakan saja
myData
seperti biasa.Dengan cara ini, Anda bisa membuang myLiveData dari fungsi mana pun. Misalnya, jika Anda ingin memperbarui setiap beberapa detik, cukup gabungkan
$.getJSON
baris itu dalam sebuah fungsi dan panggilsetInterval
. Anda tidak perlu melepas ikatan selama Anda ingat untuk tetap memasukkanmyLiveData.removeAll();
tali pengikat .Kecuali data Anda sangat besar, pengguna bahkan tidak akan dapat memperhatikan waktu di antara menyetel ulang array dan kemudian menambahkan kembali data terbaru.
sumber
Saya mengalami masalah kebocoran memori baru-baru ini dan
ko.cleanNode(element);
tidak akan melakukannya untuk saya - yako.removeNode(element);
. Kebocoran memori Javascript + Knockout.js - Bagaimana cara memastikan objek sedang dihancurkan?sumber
Pernahkah Anda memikirkan tentang ini:
Saya datang dengan ini karena di Knockout, saya menemukan kode ini
Jadi bagi saya itu bukan masalah yang sudah terikat, itu adalah kesalahan yang tidak diketahui dan ditangani ...
sumber
Saya telah menemukan bahwa jika model tampilan berisi banyak pengikatan div, cara terbaik untuk menghapusnya
ko.applyBindings(new someModelView);
adalah dengan menggunakan:ko.cleanNode($("body")[0]);
Ini memungkinkan Anda untuk memanggil model baruko.applyBindings(new someModelView2);
secara dinamis tanpa khawatir model tampilan sebelumnya masih terikat.sumber
$("body")[0]
adalahdocument.body
.