seperti yang dikatakan Ven, Anda mengembalikan objek yang berbeda (tidak identik) pada setiap $digest
siklus, atau Anda terlalu sering mengubah data.
Solusi tercepat untuk mengetahui bagian mana dari aplikasi Anda yang menyebabkan perilaku ini adalah:
- hapus semua HTML yang mencurigakan - pada dasarnya hapus semua html Anda dari template, dan periksa apakah tidak ada peringatan
- jika tidak ada peringatan - tambahkan bagian kecil dari html yang Anda hapus dan periksa apakah masalahnya kembali
- ulangi langkah 2 hingga Anda mendapatkan peringatan - Anda akan mengetahui bagian mana dari html Anda yang bertanggung jawab atas masalah tersebut
- menyelidiki lebih lanjut - bagian dari langkah 3 bertanggung jawab untuk mutasi objek pada
$scope
atau mengembalikan objek non-identik pada setiap $digest
siklus.
- jika Anda masih memiliki
$digest
peringatan iterasi setelah langkah 1, Anda mungkin melakukan sesuatu yang sangat mencurigakan. Ulangi langkah yang sama untuk template induk / scope / controller
Anda juga ingin memastikan Anda tidak mengubah masukan filter kustom Anda
Perlu diingat, bahwa di JavaScript ada jenis objek tertentu yang tidak berperilaku seperti yang biasanya Anda harapkan:
new Boolean(true) === new Boolean(true) // false
new Date(0) == new Date(0) // false
new String('a') == new String('a') // false
new Number(1) == new Number(1) // false
[] == [] // false
new Array == new Array // false
({})==({}) // false
map()
dan kemudiangroupBy()
memastikan bahwa$watch
es Anda melakukan pemeriksaan kotor denganobjectEquality
$watch('myFunctionDoingGropby',callback,true)
melihat docs.angularjs.org/api/ng.$rootScope.Scope#$watch$scope
yang diberi_.map
daftar -ed sekali - tetapi dalam kasus umum, bagaimana Anda akan mempengaruhi pemeriksaan kotor tersebut dengan persamaan objek jika itu bukan dibuat secara manual$watch
yang tersandung, tapingRepeat
?Biasanya itu terjadi ketika Anda mengembalikan objek yang berbeda setiap saat.
Misalnya, jika Anda menggunakan ini di
ng-repeat
:$scope.getObj = function () { return [{a: 1}, {b: 2}]; };
Anda akan mendapatkan pesan kesalahan ini karena Angular mencoba untuk memiliki "stabilitas" dan akan menjalankan fungsi hingga mengembalikan hasil yang sama 2 kali (dibandingkan dengan
===
), yang dalam kasus kami tidak akan pernah mengembalikan nilai true karena fungsi selalu mengembalikan objek baru.console.log({} === {}); // false. Those are two different objects!
Dalam kasus ini, Anda dapat memperbaikinya dengan menyimpan objek dalam cakupan secara langsung, mis
$scope.objData = [{a: 1}, {b: 2}]; $scope.getObj = function () { return $scope.objData; };
Dengan begitu, Anda selalu mengembalikan objek yang sama!
console.log($scope.objData === $scope.objData); // true (a bit obvious...)
(Anda tidak boleh menemukan itu, bahkan pada aplikasi yang kompleks).
Pembaruan: Angular telah menambahkan beberapa penjelasan mendalam di situs web mereka .
sumber
Hanya ingin melempar solusi ini ke sini, semoga bisa membantu orang lain. Saya mendapatkan masalah iterasi ini karena saya melakukan iterasi pada properti yang dihasilkan yang membuat objek baru setiap kali dipanggil.
Saya memperbaikinya dengan meng-cache objek yang dihasilkan saat pertama kali diminta, lalu selalu mengembalikan cache jika ada. Metode dirty () juga ditambahkan, yang akan menghancurkan hasil yang di-cache sesuai kebutuhan.
Saya punya sesuatu seperti ini:
function MyObj() { var myObj = this; Object.defineProperty(myObj, "computedProperty" { get: function () { var retObj = {}; return retObj; } }); }
Dan inilah solusi yang diterapkan:
function MyObj() { var myObj = this, _cached; Object.defineProperty(myObj, "computedProperty" { get: function () { if ( !_cached ) { _cached = {}; } return _cached; } }); myObj.dirty = function () { _cached = null; } }
sumber
Ada juga kemungkinan itu tidak menjadi loop tak terbatas sama sekali. 10 iterasi bukanlah angka yang cukup besar untuk menyimpulkan dengan sejumlah kepastian. Jadi sebelum melakukan pengejaran liar, mungkin disarankan untuk mengesampingkan kemungkinan itu terlebih dahulu.
Metode termudah untuk melakukannya adalah meningkatkan jumlah loop intisari maksimum ke angka yang jauh lebih besar, yang dapat dilakukan dalam
module.config
metode, menggunakan$rootScopeProvider.digestTtl(limit)
metode. Jikainfdig
kesalahan tidak lagi muncul, Anda hanya memiliki beberapa logika pembaruan yang cukup kompleks.Jika Anda membangun data atau tampilan dengan mengandalkan jam tangan rekursif, Anda mungkin ingin mencari solusi berulang (yaitu tidak mengandalkan loop intisari baru untuk memulai) menggunakan
while
,for
atauArray.forEach
. Terkadang strukturnya sangat bersarang dan bahkan tidak rekursif, mungkin tidak banyak yang harus dilakukan dalam kasus tersebut kecuali menaikkan batas.Metode lain untuk men-debug kesalahan adalah melihat data intisari. Jika Anda cukup mencetak JSON, Anda mendapatkan array array. Setiap entri tingkat atas mewakili sebuah iterasi, setiap iterasi terdiri dari daftar entri arloji.
Misalnya, jika Anda memiliki properti yang dimodifikasi dengan
$watch
on sendiri, mudah untuk melihat bahwa nilainya berubah tanpa batas:$scope.vm.value1 = true; $scope.$watch("vm.value1", function(newValue) { $scope.vm.value1 = !newValue; });
[ [ { "msg":"vm.value1", "newVal":true, "oldVal":false } ], [ { "msg":"vm.value1", "newVal":false, "oldVal":true } ], [ { "msg":"vm.value1", "newVal":true, "oldVal":false } ], [ { "msg":"vm.value1", "newVal":false, "oldVal":true } ], [ { "msg":"vm.value1", "newVal":true, "oldVal":false } ] ]
Tentu saja dalam proyek yang lebih besar ini mungkin tidak sesederhana itu, terutama karena
msg
bidang sering memiliki nilai"fn: regularInterceptedExpression"
jika jam tangan adalah{{ }}
interpolasi.Selain itu, metode yang telah disebutkan, seperti memotong HTML untuk menemukan sumber masalah, tentu saja membantu.
sumber
Saya memiliki masalah yang sama - saya membuat tanggal baru setiap saat. Jadi bagi siapa pun yang berurusan dengan tanggal, saya mengubah semua panggilan seperti ini:
var date = new Date(); // typeof returns object
untuk:
var date = new Date().getTime(); // typeof returns number
Menginisialisasi angka alih-alih objek tanggal memecahkannya untuk saya.
sumber
cara mudahnya adalah: gunakan angular.js, bukan file min. buka dan temukan barisnya:
if ((dirty || asyncQueue.length) && !(ttl--)) {
tambahkan baris di bawah ini:
console.log("aaaa",watch)
lalu segarkan laman Anda, di konsol alat pengembangan, Anda akan menemukan kode kesalahan.
sumber
Ini bug yang diketahui
ui-router
, ini membantu kami: https://github.com/angular-ui/ui-router/issues/600sumber
Saya juga ingin menyebutkan bahwa saya menerima pesan kesalahan ini ketika saya mengalami kesalahan ketik di templateUrl dari arahan kustom yang saya miliki di proyek saya. Karena salah ketik, template tidak dapat dimuat.
/* @ngInject */ function topNav() { var directive = { bindToController: true, controller: TopNavController, controllerAs: 'vm', restrict: 'EA', scope: { 'navline': '=', 'sign': '=' }, templateUrl: 'app/shared/layout/top-navTHIS-IS-A-TYPO.html' };
Lihat di tab jaringan alat dev browser web Anda, dan lihat apakah ada sumber daya yang mengalami kesalahan 404.
Mudah untuk dilupakan, karena pesan kesalahannya sangat samar dan tampaknya tidak berhubungan dengan masalah sebenarnya.
sumber
Saya mengalami masalah ini dalam proyek saya karena .otherwise () kehilangan definisi rute saya dan saya memilih rute yang salah.
sumber
Saya mengalami masalah ini karena saya melakukan ini
var variableExpense = this.lodash.find(product.variableExpenseList, (ve) => { return ve.rawMaterial.id = rawMaterial.id; });
Alih-alih ini: (perhatikan = vs ===), tes unit saya mulai rusak dan saya menemukan kebodohan saya
var variableExpense = this.lodash.find(product.variableExpenseList, (ve) => { return ve.rawMaterial.id === rawMaterial.id; });
sumber
Saya mengalami masalah ini di mana saya membutuhkan tooltip dinamis ... itu menyebabkan sudut menghitung ulang setiap kali sebagai nilai baru (meskipun itu sama). Saya membuat fungsi untuk menyimpan nilai yang dihitung seperti ini:
$ctrl.myObj = { Title: 'my title', A: 'first part of dynamic toolip', B: 'second part of dynamic tooltip', C: 'some other value', getTooltip: function () { // cache the tooltip var obj = this; var tooltip = '<strong>A: </strong>' + obj.A + '<br><strong>B: </strong>' + obj.B; var $tooltip = { raw: tooltip, trusted: $sce.trustAsHtml(tooltip) }; if (!obj.$tooltip) obj.$tooltip = $tooltip; else if (obj.$tooltip.raw !== tooltip) obj.$tooltip = $tooltip; return obj.$tooltip; } };
Kemudian di html, saya mengaksesnya seperti ini:
<input type="text" ng-model="$ctrl.myObj.C" uib-tooltip-html="$ctrl.myObj.getTooltip().trusted">
sumber
beginilah cara saya mendekatinya dan menemukan solusi: Saya memeriksa teksnya, itu menunjukkan:
Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!
Pengamat diaktifkan dalam 5 iterasi terakhir: [[{"msg": "statement === statment && functionCall ()", "newVal": [{"id": 7287, "referen ...
jadi jika Anda bisa melihat
itulah pernyataan yang menghasilkan kesalahan. Saya memeriksa fungsi yang dipanggil dalam pesan ini, saya mengembalikan (salah) dari semuanya hanya untuk menentukan mana yang bermasalah. salah satunya memanggil fungsi yang terus mengubah pengembalian, yang merupakan masalah.
sumber
Kedengarannya gila, saya memperbaiki kesalahan ini hanya dengan memulai ulang browser saya ketika tiba-tiba terpotong.
Jadi salah satu solusinya adalah dengan menghapus cache browser Anda atau mencoba memulai ulang browser.
sumber