[英]How to watch all changes on a Scope in AngularJS?
Angular的$ watch函數允許在指定的屬性更改時觸發事件,如下所示。 當范圍發生任何變化時,是否有類似的方式來監聽事件?
// works
$scope.$watch("someval", function() { }, true);
$scope.$watch(function(scope){ return scope.someval; }, function() { }, true);
// doesn't work
$scope.$watch("this", function() { }, true);
$scope.$watch(function(scope){ return scope; }, function() { }, true);
我相信你不能注意$scope
變化(除了使用@ ValentynShybanov的消化)。 你最接近的事情是觀察摘要電話:
$scope.$watch(function() {
console.log("digest called");
});
每次在作用域上調用$digest
都會調用上面的函數, 即使作用域的屬性沒有變化也是如此。
這不是直截了當的,因為范圍是一個普通的對象。 這是Backbone,您可以訂閱所有事件,但為此您的模型應擴展專有接口 - Backbone.Model
。 Angular將觀察者模式放在它的經典外觀中。 這是一個不尋常的設計決定。 基本上有一個循環,其中Angular評估被監視的表達式,當它檢測到與前一次迭代的差異時,它會通知觀察者。 一種非常有趣的方法,可能是觀察者模式的唯一替代方法(除了可能是反應式編程 ,這種情況還不常見)。
我建議使用一個函數作為監視表達式,它返回范圍的哈希值。 不幸的是,范圍在某處包含循環引用,因此JSON.stringify($scope)
等快速解決方案不起作用。 我寫了快速而骯臟的概念證明。 http://jsfiddle.net/ADukg/2544 。 無論您輸入什么文本字段,它都會打印到控制台。 String hash函數取自Javascript / jQuery中的字符串生成Hash 。
function MyCtrl($scope) {
$scope.$watch(
function($scope) {return hash($scope);},
function() {console.log("changed");}
);
}
我自己遇到了這個問題,我用類似於@ ValentynShybanov的評論解決了這個問題,但並不完全相同。 我的解決方案不要求您按照評論中的說明為所有屬性添加前綴 。
看到一個工作的plunkr
var entireScope = {};
for ( var i in $scope ){
if ( i[0] !== '$' && i !== 'this' && i !== 'constructor'){
console.log(i);
entireScope[i] = $scope[i];
}
}
$scope.entireScope = entireScope;
$scope.$watch('entireScope', function( newValue, oldValue ){
$log.info('entireScope has changed',newValue, oldValue);
}, true);
正如您所看到的那樣,解決方案完全相同,但實際上它會為范圍添加另一個屬性,而不是替換您已有的結構。 這個新屬性代表整個范圍(因此它的名字),你可以觀看它。
我編寫的循環可能過於通用,您可以使用自定義初始化替換它。 例如:
$scope.entireScope = { 'someVal' : $scope.someVal }
此解決方案可滿足您的需求,並使您無需重構代碼。
一個簡單的解決方案可能是您應該只檢查范圍的變量,但它可能是對象。
app.js
app.controller('MainController', ['$scope', function($scope){
$scope.watchable = {
'param1':'',
'param2':''
};
$scope.update = -1;
$scope.$watch('watchable', function(scope){
scope.update++;
}, true);
});
的index.html
<div ng-controller="MainController">
<input type='text' ng-model="watchable.param1">
<input type='text' ng-model="watchable.param2">
<p>param1:{{watchable.param1}}, param2:{{watchable.param2}}</p>
<p>update:{{update}}
</div>
這里的技巧是在$ watch函數的第三個參數中傳遞'true',它將執行angular.equal檢查,該檢查是按值檢查而不是簡單的引用檢查。 如果正確的話請告訴我。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.