美文网首页
AngularJs作用域高级特性,作用域属性监视、digest循

AngularJs作用域高级特性,作用域属性监视、digest循

作者: TryCatch菌 | 来源:发表于2019-07-10 11:17 被阅读0次

AngularJs作用域高级特性,作用域属性监视、digest循环等

基于AngularJS入门与进阶(江荣波 著)这本书的笔记

AngularJS 1.x的demo

AngularJS1.x和Angular2,4,5是不一样的两个东西,构建方式,语法,都很多不同


$watch方法监视作用域

在传统的JavaScript中如果要监视一个方法是比较繁琐的事情,不过在AngularJs中可以使用$watch 对对像进行手工监视,让对像发生变化的时候触发

$watch(watchFn,watchAction,deepWatch)
  • watchFn:angular表达式或函数的字符串
  • watchAction(newValue,oldValue,scope):watchFn发生变化会被调用
  • deepWatch:可选的布尔值命令检查被监控的对象的每个属性是否发生变化

示例代码

<!DOCTYPE html>
<html lang="en" ng-app="scopeApp">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script  src="/lib/angular/angular.js"></script>
    <script type="text/javascript">
        var scopeApp = angular.module("scopeApp",[]);
        scopeApp.controller("scopeController",function ($scope,$log) {
            $scope.changeNum = 0;
            $scope.$watch('userName',function (newValue,oldValue) {
                ++$scope.changeNum;
                console.log("newValue:" + newValue + " " + "oldValue:" + oldValue + " " + "changeNum:" + $scope.changeNum);
            });
        });
    </script>
</head>
<body >
    <div ng-controller="scopeController">
        <input ng-model="userName" type="text">
        <span>改变次数:{{changeNum}}</span>
    </div>
</body>
</html>

控制台输出

newValue:undefined oldValue:undefined changeNum:1
newValue:2 oldValue:undefined changeNum:2
newValue:23 oldValue:2 changeNum:3
newValue:231 oldValue:23 changeNum:4
newValue:2314 oldValue:231 changeNum:5

从控制台输出可以看出,才进去的时候新的值和旧的值都是未定义,改变次数为1,当在文本框录入一次值后,新的值变为2,旧值是未定义,改变次数为2,再次输入新值变为23,旧值变为2,改变次数为3。通过这个方法我们能很简便的监控某些特定的值或者字段。

需要注意的是,示例代码中$watch只用了两个参数,如果不定义第三个参数,默认为false,不会监控引用数据类型例如数组等类型的变化。如果需要监控引用数据类型,需要显式定义为true,就可以实现监控。

在angular 1.1.4版本之后,新增加了一个$watchCollection()方法来针对数组(也就是集合)进行监视,它的性能介于全等监视和引用监视之间,即它并不会对数组中每一项的属性进行监视,但是可以对数组的项目增减做出反应。

对于多个变量的监视变化,执行同一函数的话,可以将这几个变量转为字符串,以‘+’号隔开来进行监视

$scope.$watch('count + page',function(){
...
});
作用域监视解除

如果在某种特定的条件下需要解除监视,可以调用unbindWatcher();方法

var scopeApp = angular.module("scopeApp",[]);
        scopeApp.controller("scopeController",function ($scope,$log) {
            $scope.changeNum = 0;
            // $watch 回调函数可以解除监视
            var unbindWatcher = $scope.$watch('userName',function (newValue,oldValue) {
                ++$scope.changeNum;
                console.log("newValue:" + newValue + " " + "oldValue:" + oldValue + " " + "changeNum:" + $scope.changeNum);
                if($scope.changeNum == 3){
                    unbindWatcher();
                }
            });
        });

示例代码样式在改变次数到3后,就不会再出发watch方法了

newValue:undefined oldValue:undefined changeNum:1
newValue:2 oldValue:undefined changeNum:2
newValue:22 oldValue:2 changeNum:3
$apply$digest

在AngularJS作用域中的数据发生变化时,会自动触发digest循环,从而达到自动更新视图,实现数据的双向绑定。不过如果我们在angularjs中使用了原生的javascript改变了作用域中的值,是不会更新视图的,这个时候就需要手动调用`apply来触发 $digest`。

示例代码,就是书中的代码,使用setTimeout的JS触发,可以发现控制台输出了改变的值,但是视图中没有改变

<!DOCTYPE html>
<html lang="en" ng-app="scopeApp">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script  src="/lib/angular/angular.js"></script>
    <script type="text/javascript">
        var scopeApp = angular.module("scopeApp",[]);
        scopeApp.controller("scopeController",function ($scope,$log) {
            $scope.userName = '初始姓名';
            console.log("姓名" + $scope.userName);
            $scope.clickTest = function () {
                // js 延时触发
                setTimeout(function () {
                    $scope.userName = '改变姓名';
                    console.log("改变姓名" + $scope.userName);
                },1000);
            }
        });
    </script>
</head>
<body >
<div ng-controller="scopeController">
    <input value="点击测试" type="button" ng-click="clickTest()"><br/>
    <span>姓名:{{userName}}</span>
</div>
</body>
</html>
image.png

代码修改一下,能成功触发

$scope.clickTest = function () {
                // js 延时触发
                setTimeout(function () {
                    // 使用apply手工触发digest
                    $scope.$apply(function () {
                        $scope.userName = '改变姓名';
                        console.log("改变姓名" + $scope.userName);
                    });
                },1000);
            }
image.png
$timeout$interval服务介绍

JavaScript的setTimeout()方法达到延迟执行某个方法的效果。还有一个的方法setInterval(),作用是每隔一段时间调用一次方法。两个方法都需要我们手动调用$apply()方法来触发$digest循环。
,AngularJS中有对应的$timeout$interval,不需要我们手动调用apply()方法触发digest循环。

相关文章

  • AngularJs作用域高级特性,作用域属性监视、digest循

    AngularJs作用域高级特性,作用域属性监视、digest循环等 基于AngularJS入门与进阶(江荣波 著...

  • 面试涉及的知识点

    csshtml重点:javascript(闭包,作用域,高级特性) 重点:es6 async ,作用域,模块化...

  • 2018-12-18

    JS高级 作用域&作用域链 作用域: 1.作用域的个数:n(函数声明的个数)+1(全局作用域)2.作用域不会存储变...

  • AngularJs 作用域

    $rootScope 每个AngularJs应用默认有一个根作用域--$rootScope, 根作用域位于最顶层,...

  • JavaScript散乱(四、细节)

    js高级 案例问题 作用域和作用域链 全局作用域也就是window和函数作用域,不考虑es6的块级作用域前提下,作...

  • 深入理解Angular作用域

    翻译自:Understanding Scopes 摘要 在AngularJS中,子作用域通常会原型继承于其父作用域...

  • Angularjs 作用域

    非常详细? :AngularJS实例教程(二)——作用域与事件 Scope 概述, AngularJS 应用组成如...

  • angular之中,$scope $rootScope $wat

    1.背景介绍 1、AngularJS Scope(作用域) Scope(作用域)是应用在 HTML (视图)和 J...

  • 前端面试知识点

    一、作用域(全局作用域、函数作用域) 、全局作用域顾名思义:也就是挂在window上下文中的属性,或者functi...

  • js作用域

    1 - 作用域 1.1 作用域概述 全局作用域 局部作用域(函数作用域) 1.2 全局作用域 1.3 局部作用域 ...

网友评论

      本文标题:AngularJs作用域高级特性,作用域属性监视、digest循

      本文链接:https://www.haomeiwen.com/subject/gwvckctx.html