如何在AngularJS中使用$ scope.$ watch和$ scope.$ apply? [英] How do I use $scope.$watch and $scope.$apply in AngularJS?

查看:92
本文介绍了如何在AngularJS中使用$ scope.$ watch和$ scope.$ apply?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道如何使用$scope.$watch$scope.$apply.官方文档没有帮助.

我不明白的是什么

  • 他们是否已连接到DOM?
  • 如何更新对模型的DOM更改?
  • 它们之间的连接点是什么?

我尝试了本教程,但需要理解$watch$apply是理所当然的.

$apply$watch的功能是什么,如何正确使用它们?

解决方案

您需要了解AngularJS的工作原理才能理解它.

摘要循环和$ scope

首先,AngularJS定义了所谓的消化周期的概念.此循环可以视为一个循环,在此循环中,AngularJS将检查所有$scope对所有变量 watched 是否有任何更改.因此,如果您在控制器中定义了$scope.myVar并且该变量已标记为要监视,那么您将隐式告诉AngularJS在循环的每次迭代中监视myVar的更改.

一个自然的后续问题是:是否正在监视与$scope关联的所有内容?幸运的是,没有.如果您要监视$scope中每个对象的更改,则摘要循环很快就会花费很多时间来评估,并且您会很快遇到性能问题.这就是AngularJS团队为我们提供了两种方法来声明某些$scope变量被监视的原因(请参见下文).

$ watch帮助监听$ scope的变化

有两种方法可以声明$scope变量是否被监视.

  1. 通过表达式<span>{{myVar}}</span>
  2. 在模板中使用它
  3. 通过$watch服务手动添加

广告1) 这是最常见的情况,我敢肯定您之前已经看过它,但是您不知道这是在后台创建手表的.是的,它有!使用AngularJS指令(例如ng-repeat)也可以创建隐式监视.

广告2) 这就是您创建自己的手表的方式. $watch服务可帮助您在$scope附加的某些值发生更改时运行某些代码.它很少使用,但有时会有所帮助.例如,如果您希望每次"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可以将更改与摘要周期集成在一起

您可以将 $apply函数视为一种集成机制.您会看到,每次直接更改附加到$scope 对象的某些监视的变量时,AngularJS都会知道该更改已发生.这是因为AngularJS已经知道监视这些更改.因此,如果发生在框架管理的代码中,则摘要循环将继续进行.

但是,有时您想在AngularJS世界之外更改一些值,然后看到更改能够正常传播. 考虑一下-您有一个$scope.myVar值,它将在jQuery的$.ajax()处理程序中进行修改.这将在将来的某个时刻发生. AngularJS不能等待这种情况发生,因为尚未指示它必须等待jQuery.

为解决此问题,引入了$apply.它使您可以显式启动消化周期.但是,您仅应使用此方法将某些数据迁移到AngularJS(与其他框架集成),而切勿将此方法与常规AngularJS代码结合使用,因为AngularJS会抛出错误.

所有这些与DOM有什么关系?

好吧,既然您已经知道了所有这些,那么您应该再次真正按照本教程进行操作.只要没有任何变化,摘要周期就可以通过评估附加到所有$scope的每个观察程序来确保UI和JavaScript代码保持同步.如果摘要循环中没有更多更改,则认为已完成.

您可以在Controller中显式地将对象附加到$scope对象,也可以直接在视图中以{{expression}}形式声明它们.

我希望这有助于澄清有关这一切的一些基本知识.

更多读数:

  • this tutorial, but it takes the understanding of $watch and $apply for granted.

    What do $apply and $watch do, and how do I use them appropriately?

    解决方案

    You need to be aware about how AngularJS works in order to understand it.

    Digest cycle and $scope

    First and foremost, AngularJS defines a concept of a so-called digest cycle. 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 $scopes. 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.

    A natural follow-up question would be: Is everything attached to $scope being watched? 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. That is why the AngularJS team gave us two ways of declaring some $scope variable as being watched (read below).

    $watch helps to listen for $scope changes

    There are two ways of declaring a $scope variable as being watched.

    1. By using it in your template via the expression <span>{{myVar}}</span>
    2. By adding it manually via the $watch service

    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. Yes, it had! Using AngularJS directives (such as ng-repeat) can also create implicit watches.

    Ad 2) This is how you create your own watches. $watch service helps you to run some code when some value attached to the $scope has changed. 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:

    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

    You can think of the $apply function as of an integration mechanism. You see, each time you change some watched variable attached to the $scope object directly, AngularJS will know that the change has happened. This is because AngularJS already knew to monitor those changes. 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. Consider this - you have a $scope.myVar value which will be modified within a jQuery's $.ajax() handler. 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.

    To tackle this, $apply has been introduced. It lets you start the digestion cycle explicitly. However, you should only use this to migrate some data to AngularJS (integration with other frameworks), but never use this method combined with regular AngularJS code, as AngularJS will throw an error then.

    How is all of this related to the DOM?

    Well, you should really follow the tutorial again, now that you know all this. The digest cycle will make sure that the UI and the JavaScript code stay synchronised, by evaluating every watcher attached to all $scopes as long as nothing changes. If no more changes happen in the digest loop, then it's considered to be finished.

    You can attach objects to the $scope object either explicitly in the Controller, or by declaring them in {{expression}} form directly in the view.

    I hope that helps to clarify some basic knowledge about all this.

    Further readings:

    这篇关于如何在AngularJS中使用$ scope.$ watch和$ scope.$ apply?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆