Saya membuat UI izin, saya memiliki daftar izin dengan daftar pilihan di samping setiap izin. Izin diwakili oleh larik objek yang dapat diamati yang terikat ke daftar pilihan:
<div data-bind="foreach: permissions">
<div class="permission_row">
<span data-bind="text: name"></span>
<select data-bind="value: level, event:{ change: $parent.permissionChanged}">
<option value="0"></option>
<option value="1">R</option>
<option value="2">RW</option>
</select>
</div>
</div>
Sekarang masalahnya adalah ini: peristiwa perubahan dimunculkan saat UI baru saja terisi untuk pertama kalinya. Saya memanggil fungsi ajax saya, mendapatkan daftar izin dan kemudian acara dimunculkan untuk setiap item izin. Ini sebenarnya bukan perilaku yang saya inginkan. Saya ingin itu dimunculkan hanya ketika pengguna benar-benar memilih nilai baru untuk izin di daftar pilih , bagaimana saya bisa melakukannya?
sumber
select
elemen tersebut. Namun, meskipun nilai awal yang dipilih cocok dengan salah satu opsi, hal itu tetap memicuchange
peristiwa. Ketika saya menerapkanif
blok sederhana ini di pawang, semuanya bekerja seperti yang diharapkan. Coba cara ini dulu. Terima kasih, @Sarath!Ini hanya tebakan, tapi saya pikir ini terjadi karena
level
ini adalah angka. Dalam hal ini,value
pengikatan akan memicuchange
peristiwa untuk diperbaruilevel
dengan nilai string. Oleh karena itu, Anda dapat memperbaikinya dengan memastikanlevel
adalah string untuk memulai.Selain itu, cara yang lebih "Knockout" untuk melakukan ini adalah dengan tidak menggunakan event handler, tetapi menggunakan observasi dan langganan. Buatlah
level
observasi dan kemudian tambahkan langganan padanya, yang akan dijalankan setiap kali adalevel
perubahan.sumber
Berikut adalah solusi yang dapat membantu mengatasi perilaku aneh ini. Saya tidak dapat menemukan solusi yang lebih baik daripada meletakkan tombol untuk memicu peristiwa perubahan secara manual.
EDIT: Mungkin penjilidan khusus seperti ini dapat membantu:
ko.bindingHandlers.changeSelectValue = { init: function(element,valueAccessor){ $(element).change(function(){ var value = $(element).val(); if($(element).is(":focus")){ //Do whatever you want with the new value } }); } };
Dan di atribut data-bind pilih Anda tambahkan:
sumber
Saya menggunakan penjilidan khusus ini (berdasarkan biola ini oleh RP Niemeyer, lihat jawabannya untuk ini pertanyaan ), yang memastikan nilai numerik dikonversi dengan benar dari string ke angka (seperti yang disarankan oleh solusi Michael Best):
Javascript:
ko.bindingHandlers.valueAsNumber = { init: function (element, valueAccessor, allBindingsAccessor) { var observable = valueAccessor(), interceptor = ko.computed({ read: function () { var val = ko.utils.unwrapObservable(observable); return (observable() ? observable().toString() : observable()); }, write: function (newValue) { observable(newValue ? parseInt(newValue, 10) : newValue); }, owner: this }); ko.applyBindingsToNode(element, { value: interceptor }); } };
Contoh HTML:
<select data-bind="valueAsNumber: level, event:{ change: $parent.permissionChanged }"> <option value="0"></option> <option value="1">R</option> <option value="2">RW</option> </select>
sumber
Jika Anda menggunakan observable dan bukan nilai primitif, pemilihan tidak akan memunculkan peristiwa perubahan pada pengikatan awal. Anda dapat terus terikat ke acara perubahan, daripada berlangganan langsung ke yang dapat diamati.
sumber
Cepat dan kotor, menggunakan bendera sederhana:
var bindingsApplied = false; var ViewModel = function() { // ... this.permissionChanged = function() { // ignore, if flag not set if (!flag) return; // ... }; }; ko.applyBindings(new ViewModel()); bindingsApplied = true; // done with the initial population, set flag to true
Jika ini tidak berhasil, coba gabungkan baris terakhir dalam setTimeout () - peristiwa asinkron, jadi mungkin yang terakhir masih menunggu saat applyBindings () sudah dikembalikan.
sumber
Saya memiliki masalah serupa dan saya baru saja memodifikasi event handler untuk memeriksa jenis variabel. Jenis ini hanya disetel setelah pengguna memilih nilai, bukan saat halaman pertama kali dimuat.
self.permissionChanged = function (l) { if (typeof l != 'undefined') { ... } }
Sepertinya ini berhasil untuk saya.
sumber
Gunakan ini:
this.permissionChanged = function (obj, event) { if (event.type != "load") { } }
sumber
Coba yang ini:
self.GetHierarchyNodeList = function (data, index, event) { debugger; if (event.type != "change") { return; } } event.type == "change" event.type == "load"
sumber
Jika Anda bekerja menggunakan Knockout, gunakan fungsi kunci dari fungsi knockout yang dapat diamati.
Gunakan
ko.computed()
metode dan lakukan serta picu panggilan ajax dalam fungsi itu.sumber