无法获取未定义或 null 引用的属性“title”_AngularJs作用域高级特性,作用域属性监视、digest循环等

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:可选的布尔值命令检查被监控的对象的每个属性是否发生变化

示例代码

    Title
改变次数:{{changeNum}}

控制台输出

newValue:undefined oldValue:undefined changeNum:1newValue:2 oldValue:undefined changeNum:2newValue:23 oldValue:2 changeNum:3newValue:231 oldValue:23 changeNum:4newValue: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:1newValue:2 oldValue:undefined changeNum:2newValue:22 oldValue:2 changeNum:3
$apply与$digest

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

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

    Title
姓名:{{userName}}
2d8c7d50c1c1554481ecdb4736cc662e.png

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

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

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

AngularJS中有对应的`$timeout`和`$interval`,不需要我们手动调用$apply()方法触发$digest循环。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值