Xem http://docs.angularjs.org/error/$rootScope:inprog
Vấn đề phát sinh khi bạn có một cuộc gọi đến $apply
đôi khi được chạy không đồng bộ bên ngoài mã Angular (khi sử dụng $ nên được sử dụng) và đôi khi đồng bộ bên trong mã Angular (gây ra $digest already in progress
lỗi).
Điều này có thể xảy ra, ví dụ, khi bạn có một thư viện tìm nạp không đồng bộ các mục từ máy chủ và lưu trữ chúng. Lần đầu tiên một mục được yêu cầu, nó sẽ được truy xuất không đồng bộ để không chặn thực thi mã. Tuy nhiên, lần thứ hai, mục đã có trong bộ đệm để có thể truy xuất đồng bộ.
Cách để ngăn chặn lỗi này là đảm bảo rằng mã mà các cuộc gọi $apply
được chạy không đồng bộ. Điều này có thể được thực hiện bằng cách chạy mã của bạn trong một cuộc gọi đến $timeout
với độ trễ được đặt thành 0
(là mặc định). Tuy nhiên, việc gọi mã của bạn bên trong $timeout
sẽ loại bỏ sự cần thiết phải gọi $apply
, vì $ timeout sẽ kích hoạt một mã khác$digest
chu kỳ , do đó sẽ thực hiện tất cả các cập nhật cần thiết, v.v.
Giải pháp
Nói tóm lại, thay vì làm điều này:
... your controller code...
$http.get('some/url', function(data){
$scope.$apply(function(){
$scope.mydate = data.mydata;
});
});
... more of your controller code...
làm cái này:
... your controller code...
$http.get('some/url', function(data){
$timeout(function(){
$scope.mydate = data.mydata;
});
});
... more of your controller code...
Chỉ gọi $apply
khi bạn biết mã đang chạy, mã sẽ luôn được chạy bên ngoài mã Angular (ví dụ: lệnh gọi tới $ áp dụng của bạn sẽ xảy ra bên trong một cuộc gọi lại được gọi bằng mã bên ngoài mã Angular của bạn).
Trừ khi một người nào đó là nhận thức của một số bất lợi ảnh hưởng lớn đến việc sử dụng $timeout
qua $apply
, tôi không thấy lý do tại sao bạn có thể không luôn luôn sử dụng $timeout
(với không chậm trễ) thay vì $apply
, vì nó sẽ làm khoảng điều tương tự.