关于AngularJs中监听事件及脏循环的理解

Posted 需要学习的人

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于AngularJs中监听事件及脏循环的理解相关的知识,希望对你有一定的参考价值。

可能很多刚入行或者刚学习的前端对于AngularJs中的一些事件或者概念感觉不理解或者没有思路,今天让我们一起来剖析一下AngularJs中的一些事件。

AngularJs中对于的监听事件会用到一个scope函数$watch,它包含了三个参数,首先我们在概念上来了解一下:

$watch是一个scope函数,用于监听模型变化,当你的模型部分发生变化时它会通知你。

$watch(watchExpression, listener, objectEquality);

每个参数的说明如下:

watchExpression(必须):监听的对象,它可以是一个string,将被计算为表达式 ,或函数如function(){return $scope.name}。

listener:当watchExpression(监听对象)变化时会被调用的函数或者表达式,它接收3个参数:newValue(新值), oldValue(旧值), scope(作用域的引用)

objectEquality:是否深度监听,如果设置为true,它告诉Angular检查所监控的对象中每一个属性的变化. 如果你希望监控数组的个别元素或者对象的属性而不是一个普通的值, 那么你应该使用它。

我写了一个小例子,可能会让大家更好的了解监听模型变化的过程,以下部分是html代码:

<!doctype html>
<html ng-app="exampleApp">
<head>
    <meta charset="utf-8">
    <title></title>
    <link href="../css/bootstrap.css" rel="stylesheet">  //导入了本地bootstrap的框架
</head>

<body ng-controller = "simpleCtrl">
<div class="container">
    <div class="well">

        <div class="form-group">
            <input class="form-control" ng-model="name" type="text">
        </div>
    </div>
</div>
</body>

</html>
View Code

然后导入本地的AngularJs框架的文件,javascript代码如下:

<script src="../angular.min.js"></script>    //导入本地AngularJs文件
    <script>
        angular.module("exampleApp", [])
                .controller("simpleCtrl", function ($scope, $rootScope) {
                    $scope.count = 0;
                    $scope.name = \'\';
                    $scope.$watch(\'name\', function(){  //监听数据模型发生的变化
                        console.log($scope.count++);
                    });
                });
    </script>
View Code

代码运行后的结果为

 当用户与输入框中的内容发生交互事件时监听事件被触发(无论是增加还是删除),运行结果如下:

 

接下来为大家分享下脏循环,Angular会运行一个函数$digest来检查scope模型中的数据是否发生了变化。 在$digest循环中,watchers会被触发。当一个watcher被触发时,AngularJS会检测它所监听的scope模型,如果监听对象发生了变化那么关联到该watcher的回调函数就会被调用。 这种方法叫做脏检查。

在angular程序初始化时,会将绑定对象的属性添加为监听对象(watcher),也就是说一个$scope对象绑定了N个属性,就会添加N个watcher。 angular什么时候去脏检查呢?angular所定义的方法中都会触发$digest事件,比如:controller初始化的时候,所有以ng-开头的指令执行后,都会触发脏检查 用户与视图发生交互行为以后会触发脏检查。

调用$digest方法: $scope.$digest();

但是这里就又要牵扯到另一个函数,因为AngularJS并不直接调用$digest(),而是调用$scope.$apply(),$apply方法就是将$digest方法包装了一层,会调用$rootScope.$digest()。因此,一轮$digest循环在$rootScope开始,随后会访问到所有的children scope中的watchers。 $apply()方法接受一个可选参数,可以是string,string将被看作表达式并计算结果,也可以是函数。

当接受function作为参数,会执行该function并且触发一轮$digest循环。 不接受任何参数,触发一轮$digest循环会,检查该$scope里的所有监听的属性。 如果你在AngularJS上下文之外的任何地方修改了model,那么你就需要通过手动调用$apply()来通知AngularJS。

这里有个小例子效果图如下:

 

因为这里设置了延时触发,所以一段时间过后:

下面是实现代码部分,html代码如下:

<!DOCTYPE html>
<html lang="en" ng-app="myApp">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>

<body ng-controller="MesCtrl">
  {{message}}
</body>

</html>
View Code

javaScript代码如下:

<script src="angular.min.js"></script>
<script>
    angular.module("myApp",[]).controller("MesCtrl", function ($scope) {
        $scope.message = "原来的信息";
        $scope.getMessage = function(){
            setTimeout(function(){
                $scope.$apply(function(){
                    $scope.message = "两秒钟之后更新";
                    console.log(\'message:\' +$scope.message);
//                $scope.$apply();   第二种调用方法
                })
            },2000)
        }
        $scope.getMessage();
    });
</script>
View Code

 

以上就是我所理解的AngularJs中的部分内容,希望大家有什么质疑或见解可以放在评论栏,大家吃好喝好,回见。

 

以上是关于关于AngularJs中监听事件及脏循环的理解的主要内容,如果未能解决你的问题,请参考以下文章

angularjs怎样更改子作用域的值

AngularJS - $destroy 是不是删除事件监听器?

怎样理解js中的事件监听

AngularJs-destroy事件 (页面离开事件)

angularJS中如何写自定义指令

angularJS中如何写自定义指令