Peristiwa onchange untuk elemen yang memiliki cakupan isolate dipicu sebelum pembaruan model.
Contoh:
<!doctype html>
<html ng-app="App">
<head>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.js"></script>
<script src="http://code.angularjs.org/1.0.6/angular.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<script type="text/javascript">
"use strict"
var App = angular.module('App', []);
App.controller('Ctrl', function ($scope,$timeout) {
$scope.change1 = function () {
console.warn("inside change", $scope.y);
}
$scope.change2 = function () {
console.warn("inside change", $scope.x);
}
});
App.directive("wminput", function () {
return {
restrict: "E",
replace: true,
scope: {
"onChange":"&",
"value": "="
},
template: '<input type="text" data-ng-model="value" data-ng-change="onChange();">'
}
});
</script>
</head>
<body>
<div data-ng-controller="Ctrl">
"Onchange will be triggered after the model update"
<input data-ng-change="change1()" data-ng-model="y">
<br><br>
"Onchange will be triggered before the model update"
<wminput on-change="change2()" value="x"></wminput>
</div>
</body>
</html>
Kasus sudut yang menarik ... http://plnkr.co/edit/lsrga8qMcbgNWATrVht3?p=preview
Ini terjadi hanya jika fungsi onChange didelegasikan ke cakupan induk lebar pengikatan '&'.
Kami telah mengerjakan alat RAD berdasarkan angularjs.
Ini adalah bug utama karena setiap widget dalam aplikasi memiliki isolateScope.
Kami telah menyelesaikan masalah dengan membuat metode proxy untuk onChange.
Lihat di: https://studio.wavemaker.com/
Salam, Vinay
Bisakah Anda memposting contoh proxy ini dan cara penggunaannya? Mungkin membantu dalam debugging ini.
Lihat contohnya di: http://plnkr.co/edit/Xe6ErQrg7WL6aAIoM9Gd?p=preview
Apakah akan diperbaiki dalam waktu dekat? Ini sangat membingungkan.
Setelah pertimbangan lebih lanjut, saya harus mengatakan bahwa ini adalah perilaku yang diharapkan .. Dalam contoh plnkr, nilai ngModel adalah dua string terikat antara pengontrol dan lingkup direktif. Sekarang, saat Anda mengubah nilai di direktif, ngModel akan memperbarui cakupan _isolate_ terlebih dahulu, dan mengaktifkan ngChange di intisari yang sama. Karena pengikatan dua arah belum mengambil perubahan pada lingkup direktif, ngChange dalam lingkup induk mendapatkan nilai "lama" x
. Sekarang pengamat pengikatan dua arah memerlukan setidaknya dua siklus intisari untuk menstabilkan nilai, sehingga cakupan pengontrol hanya diperbarui setelah ngChange dipanggil.
Saya setuju bahwa ini membingungkan, tetapi begitulah cara kerjanya. Anda dapat mengatasinya dengan mengikat objek ke direktif yang menyimpan nilai yang Anda ikat ke ngModel. Dengan begitu, nilai ditetapkan dengan referensi di isolate dan cakupan pengontrol secara bersamaan dan tersedia saat ngChange dijalankan: http://plnkr.co/edit/fs7S6yX1a5aeo1Ese522?p=preview
Narretz, saya sangat tidak setuju. Ada kontrak yang dibuat dengan pengembang yang menggunakan kode yang diutamakan pengikatan dua arah. Saat perubahan dilakukan di mana saja di sepanjang rantai pengikatan, seluruh rantai harus diperbarui sebelum melanjutkan. Jadi, bahkan jika direktif lain mewarisi dari direktif ini, dan sesuatu yang lebih jauh terikat ke pengikatan pengikatan ... jika model itu diperbarui, model lingkup pengontrol asli di bagian bawah tumpukan harus diperbarui dalam siklus intisari yang sama sebelumnya melanjutkan ke fungsi lainnya. Itu yang diharapkan dari konsumen.
Sedikit terkait, dan juga membingungkan. Saat menggunakan ngChange
untuk memicu validasi di bidang lain yang berbagi ngModel
, perubahan dipicu sebelum $modelValue
diperbarui. Membuat validasi berbelit-belit.
Menggunakan $timeout
sebagai solusi. Masih bingung kenapa itu dibutuhkan.
Contoh:
http://codepen.io/jakobadam/pen/qmBdrJ?editors=1010
salam, Jakob
Apakah ada rencana untuk meninjau kembali masalah ini? Mungkin buka kembali?
Saya mengalami masalah ini dan membaca komentar, sementara cara kerjanya saat ini karena ruang lingkup isolate masuk akal; hasil yang datang dari mengharapkan model yang diperbarui ketika panggilan on-change diaktifkan dan mendapatkan model satu iterasi sebelumnya jelas bukan perilaku yang Anda harapkan sebagai pengembang.
Saya mematuhi pertanyaan, apakah ini akan ditinjau kembali?
Saya rasa tidak. Perilaku saat ini diharapkan dan meskipun tidak diinginkan dalam beberapa kasus, setidaknya ada banyak kasus di mana itu. Mengubahnya sekarang akan (a) menjadi perubahan yang mengganggu dan (b) membuat banyak kasus penggunaan tidak didukung (mis. Di mana Anda ingin ngChange
untuk mengubah nilai _before_ memperbarui induknya). Ini adalah salah satu kasus di mana Anda tidak dapat membuat semua orang senang, jadi kami harus tetap menggunakan versi yang:
Implementasi ngChange
ini terikat erat dengan konsep ngModel
. Pengikatan arahan adalah konsep yang sepenuhnya independen. Keduanya dapat bekerja sama dengan baik, tetapi tidak mempengaruhi implementasi / kerja internal satu sama lain.
Seperti yang telah disebutkan, jika callback spesifik Anda memerlukan akses ke nilai yang diperbarui, ada beberapa opsi:
Teruskan nilai yang diperbarui sebagai argumen ke callback.
Jika Anda membutuhkannya untuk dijalankan secara asinkron (yaitu setelah intisari selesai dan semua binding telah disebarkan), Anda selalu dapat menggunakan $timeout
di dalam callback.
Jika Anda menginginkan versi "asinkron" dari ngChange
, penerapannya sebagai petunjuk kustom juga mudah. (Anda juga dapat menimpa direktif bawaan, tetapi saya pasti tidak akan merekomendasikannya.) Misalnya:
.directive('myAsyncChange', function($timeout) {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, element, attr, ctrl) {
ctrl.$viewChangeListeners.push(function() {
$timeout(function() {
scope.$eval(attr.myAsyncChange);
});
});
}
};
});
<input ng-model="foo" my-async-change="onChange()" />
Komentar yang paling membantu
Narretz, saya sangat tidak setuju. Ada kontrak yang dibuat dengan pengembang yang menggunakan kode yang diutamakan pengikatan dua arah. Saat perubahan dilakukan di mana saja di sepanjang rantai pengikatan, seluruh rantai harus diperbarui sebelum melanjutkan. Jadi, bahkan jika direktif lain mewarisi dari direktif ini, dan sesuatu yang lebih jauh terikat ke pengikatan pengikatan ... jika model itu diperbarui, model lingkup pengontrol asli di bagian bawah tumpukan harus diperbarui dalam siklus intisari yang sama sebelumnya melanjutkan ke fungsi lainnya. Itu yang diharapkan dari konsumen.