本文翻译自:How do I use $scope.$watch and $scope.$apply in AngularJS?
I don't understand how to use $scope.$watch
and $scope.$apply
. 我不明白如何使用$scope.$watch
和$scope.$apply
。 The official documentation isn't helpful. 官方文档没有帮助。
What I don't understand specifically: 我不明白的是:
- Are they connected to the DOM? 他们连接到DOM吗?
- How can I update DOM changes to the model? 如何更新对模型的DOM更改?
- What is the connection point between them? 它们之间的连接点是什么?
I tried this tutorial , but it takes the understanding of $watch
and $apply
for granted. 我尝试了本教程 ,但需要理解$watch
和$apply
是理所当然的。
What do $apply
and $watch
do, and how do I use them appropriately? $apply
和$watch
什么作用,如何正确使用它们?
#1楼
参考:https://stackoom.com/question/11PTM/如何在AngularJS中使用-scope-watch和-scope-apply
#2楼
You need to be aware about how AngularJS works in order to understand it. 您需要了解AngularJS的工作原理才能理解它。
Digest cycle and $scope 消化周期和作用域
First and foremost, AngularJS defines a concept of a so-called digest cycle . 首先,AngularJS定义了所谓的摘要循环的概念。 This cycle can be considered as a loop, during which AngularJS checks if there are any changes to all the variables watched by all the $scope
s. 这个周期可以看作是一个循环,在此期间AngularJS检查所有$scope
监视的所有变量是否有任何更改。 So if you have $scope.myVar
defined in your controller and this variable was marked for being watched , then you are implicitly telling AngularJS to monitor the changes on myVar
in each iteration of the loop. 因此,如果您在控制器中定义了$scope.myVar
且该变量被标记为watched ,那么您将隐式告诉AngularJS在循环的每次迭代中监视myVar
的更改。
A natural follow-up question would be: Is everything attached to $scope
being watched? 一个自然的后续问题是:是否正在监视$scope
附带的所有内容? Fortunately, no. 幸运的是,没有。 If you would watch for changes to every object in your $scope
, then quickly a digest loop would take ages to evaluate and you would quickly run into performance issues. 如果您要监视$scope
每个对象的更改,则摘要循环很快就会花费很多时间进行评估,并且您会很快遇到性能问题。 That is why the AngularJS team gave us two ways of declaring some $scope
variable as being watched (read below). 这就是AngularJS团队为我们提供了两种方法来声明某些$scope
变量被监视的原因(请参阅下文)。
$watch helps to listen for $scope changes $ watch有助于监听$ scope的变化
There are two ways of declaring a $scope
variable as being watched. 有两种方法可以声明要监视的$scope
变量。
- By using it in your template via the expression
<span>{ {myVar}}</span>
通过表达式<span>{ {myVar}}</span>
在模板中使用它 - By adding it manually via the
$watch
service 通过$watch
服务手动添加
Ad 1) This is the most common scenario and I'm sure you've seen it before, but you didn't know that this has created a watch in the background. 广告1)这是最常见的情况,我敢肯定您之前看过它,但您不知道这是在后台创建手表的。 Yes, it had! 是的,它有! Using AngularJS directives (such as ng-repeat
) can also create implicit watches. 使用AngularJS指令(例如ng-repeat
)也可以创建隐式监视。
Ad 2) This is how you create your own watches . 广告2)这就是您制作手表的方式 。 $watch
service helps you to run some code when some value attached to the $scope
has changed. $watch
服务可帮助您在$scope
附带的某些值发生更改时运行一些代码。 It is rarely used, but sometimes is helpful. 它很少使用,但有时会有所帮助。 For instance, if you want to run some code each time 'myVar' changes, you could do the following: 例如,如果您希望每次“ myVar”更改时都运行一些代码,则可以执行以下操作:
function MyController($scope) {
$scope.myVar = 1;
$scope.$watch('myVar', function() {
alert('hey, myVar has changed!');
});
$scope.buttonClicked = function() {
$scope.myVar = 2; // This will trigger $watch expression to kick in
};
}
$apply enables to integrate changes with the digest cycle $ apply允许将更改与摘要周期集成在一起
You can think of the $apply
function as of an integration mechanism . 您可以将$apply
函数视为一种集成机制 。 You see, each time you change some watched variable attached to the $scope
object directly, AngularJS will know that the change has happened. 您会看到,每次更改直接附加到$scope
对象的某个监视变量时 ,AngularJS都会知道更改已发生。 This is because AngularJS already knew to monitor those changes. 这是因为AngularJS已经知道监视这些更改。 So if it happens in code managed by the framework, the digest cycle will carry on. 因此,如果发生在框架管理的代码中,则摘要循环将继续进行。
However, sometimes you want to change some value outside of the AngularJS world and see the changes propagate normally. 但是,有时您想在AngularJS世界之外更改一些值,并看到更改可以正常传播。 Consider this - you have a $scope.myVar
value which will be modified within a jQuery's $.ajax()
handler. 考虑这一点-您有一个$scope.myVar
值,它将在jQuery的$.ajax()
处理函数中进行修改。 This will happen at some point in future. 这将在将来的某个时刻发生。 AngularJS can't wait for this to happen, since it hasn't been instructed to wait on jQuery. AngularJS不能等待这种情况发生,因为尚未指示它等待jQuery。
To tackle this, $apply
has been introduced. 为了解决这个问题,引入了