Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在AngularJS中使用$scope.$watch和$scope.$apply?_Angularjs_Angularjs Scope - Fatal编程技术网

如何在AngularJS中使用$scope.$watch和$scope.$apply?

如何在AngularJS中使用$scope.$watch和$scope.$apply?,angularjs,angularjs-scope,Angularjs,Angularjs Scope,我不明白如何使用$scope.$watch和$scope.$apply。官方文件没有帮助 我不太明白的是: 它们是否连接到DOM 如何更新模型的DOM更改 它们之间的连接点是什么 我试过了,但对$watch和$apply的理解是理所当然的 $apply和$watch做什么,我如何恰当地使用它们?为了理解AngularJS,您需要了解AngularJS是如何工作的 摘要周期和$scope 首先,AngularJS定义了所谓的消化循环的概念。该循环可视为一个循环,在此期间,AngularJS检查

我不明白如何使用
$scope.$watch
$scope.$apply
。官方文件没有帮助

我不太明白的是:

  • 它们是否连接到DOM
  • 如何更新模型的DOM更改
  • 它们之间的连接点是什么
我试过了,但对
$watch
$apply
的理解是理所当然的


$apply
$watch
做什么,我如何恰当地使用它们?

为了理解AngularJS,您需要了解AngularJS是如何工作的

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

一个自然的后续问题是:
$scope
的所有附件都被监视了吗?幸运的是,没有。如果您关注
$scope
中每个对象的更改,那么快速的摘要循环将需要很长时间来评估,并且您将很快遇到性能问题。这就是为什么AngularJS团队给了我们两种方法来声明一些
$scope
变量为被监视变量(如下所示)

$watch有助于侦听$scope更改 有两种方法可以将
$scope
变量声明为监视变量

  • 通过表达式
    {{myVar}}
  • 通过
    $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世界之外更改一些值,并看到更改正常传播。 考虑这一点,你有一个<代码> $范围。MyVa值,它将在jQuery的<代码> $.AxAs()/<代码>处理程序中修改。这将在将来的某个时候发生。AngularJS迫不及待地等待这种情况发生,因为它没有被指示等待jQuery

    为了解决这个问题,引入了
    $apply
    。它让你明确地开始消化循环。但是,您应该只使用此方法将一些数据迁移到AngularJS(与其他框架集成),而不要将此方法与常规AngularJS代码结合使用,因为AngularJS将抛出错误

    所有这些与DOM有什么关系? 好吧,既然你已经知道了所有这些,你真的应该再次学习教程。摘要周期将通过评估所有
    $scope
    上的每个观察者(只要没有任何变化),确保UI和JavaScript代码保持同步。如果摘要循环中不再发生更改,则认为它已完成

    您可以在控制器中显式地将对象附加到
    $scope
    对象,或者直接在视图中以
    {{expression}}
    形式声明对象

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

    进一步阅读:


    在AngularJS中,我们更新模型,视图/模板“自动”(通过内置或自定义指令)更新DOM

    $apply和$watch都是作用域方法,与DOM无关

    页面(“运行时”部分)对$digest循环、$apply、$evalAsync队列和$watch列表有很好的解释。以下是文本附带的图片:

    任何代码都可以访问一个作用域——通常是控制器和指令(它们的链接函数和/或控制器)——可以设置一个“”,AngularJS将根据该作用域进行评估。每当AngularJS进入$digest循环(特别是“$watch list”循环)时,就会进行此计算。您可以查看单个作用域属性,您可以定义一个函数来同时查看两个属性,您可以查看数组的长度,等等

    当事情发生在“AngularJS内部”——例如,您在启用了AngularJS双向数据绑定(即使用ng模型)的文本框中键入内容时,$http回调会触发,等等——$apply已经被调用,因此我们在上图中的“AngularJS”矩形内。将计算所有WatchExpression(可能不止一次–直到检测不到进一步的更改)

    当事情发生在“AngularJS之外”——例如,您在指令中使用bind(),然后该事件触发,导致调用回调,或者一些jQuery注册的回调触发——我们仍然处于“本机”矩形中。如果回调代码修改了$watch正在监视的任何内容,则调用$apply t
    User: <input type="text" ng-model="user" />
    Password: <input type="password" ng-model="pass" />
    
    angular.module('MY_APP', []).controller('MyCtrl', MyCtrl)
    function MyCtrl($scope,$timeout) {
      $scope.users = [{"name": "vinoth"},{"name":"yusuf"},{"name":"rajini"}];
    
      $scope.$watch("users", function() {
        console.log("**** reference checkers $watch ****")
      });
    
      $scope.$watchCollection("users", function() {
        console.log("**** Collection  checkers $watchCollection ****")
      });
    
      $scope.$watch("users", function() {
        console.log("**** equality checkers with $watch(true) ****")
      }, true);
    
      $timeout(function(){
         console.log("Triggers All ")
         $scope.users = [];
         $scope.$digest();
    
         console.log("Triggers $watchCollection and $watch(true)")
         $scope.users.push({ name: 'Thalaivar'});
         $scope.$digest();
    
         console.log("Triggers $watch(true)")
         $scope.users[0].name = 'Superstar';
         $scope.$digest();
      });
    }
    
    app.controller('MainCtrl', function() {
      $scope.name = "vinoth";
    
      $scope.changeFoo = function() {
          $scope.name = "Thalaivar";
      }
    });
    
    {{ name }}
    <button ng-click="changeFoo()">Change the name</button>
    
    $watch(
      function(){return orders;},
      function(){Kitchen make it;}
    );