浅谈angularJS的$watch失效问题的解决方案

本文介绍了浅谈angularJS的$watch失效问题的解决方案,分享给大家,顺便给自己留个笔记

$watch方法,它可以帮助我们在每个scope中监视其中的变量。

$watch 单一的变量

对于普通的变量时,如数字,字符串等,直接如下写是可以监视到变量的变化,并执行相应的函数的。

$scope.count=1;
$scope.$watch('count',function(){
...
});

$watch 多个变量

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

//当count或page变化时,都会执行这个匿名函数
$scope.count=1;
$scope.page=1;
$scope.$watch('count + page',function(){
...
});

$watch对象或数组

发现用上面两种方法去监视数组时,会发现即使数组的内容改变了,也没有触发到这个匿名函数。之后发现watch函数其实是有三个变量的,第一个参数是需要监视的对象,第二个参数是在监视对象发生变化时需要调用的函数,实际上watch还有第三个参数,它在默认情况下是false。

当第三个参数是false时,其实watch函数监视的是数组的地址,而数组的内容的变化不会影响数组地址的变化,所以watch函数失灵了。

解决办法,就是在后面添加第三个参数为true就好(当然,也可以将这监听返回结果为JSON字符串形式的该对象或数组的的匿名函数。)

$scope.items=[
{a:1},
{a:2}
{a:3}];
$scope.$watch('items',function(){...},true);

或者将监听返回结果为JSON字符串形式的该对象或数组的的匿名函数

$scope.items=[
{a:1},
{a:2}
{a:3}];
$scope.$watch(function(){
  return JSON.stringify($scope.items);
},function(){...});

$watch 函数的返回结果

在写代码的时候,有时会遇到要监视一个函数返回的结果是否变化的情况,所以查了一下$watch 监视函数的情况。

方法1:监视对象为“函数名()”的字符串,记得加“()”!

//未完成的任务个数
$scope.unDoneCount = function() {
  var count = 0;
  angular.forEach($scope.todoList, function(todo) {
    count += todo.done ? 0 : 1;
  });
  return count;
};
//单选影响全选部分
$scope.$watch('unDoneCount()', function(nv) {
  $scope.isDoneAll = nv ? false : true;
});

方法2:在监视对象中设置为匿名函数,返回要监视的函数的返回值(绕晕了…)

$scope.$watch(function(){
  return $scope.unDoneCount();//不要忘了(),要执行的啊~
}, function(nv) {
  $scope.isDoneAll = nv ? false : true;
});

取消$watch

watch的性能消耗好像蛮大的,所以对于已经不需要监视的watch,记得定时取消掉。

至于怎么取消了…查了好久才找到的

其实每个watch函数返回的结果就是这个watch的deregisterWatch()函数

//在chrome的控制台上,断点得到的$watch的返回值
function deregisterWatch() {
  arrayRemove(array, watcher);
  lastDirtyWatch = null;
}

所以啊,要取消watch的话,一开始将$watch的返回值保存就好啦,要取消watch的时候,在调用。

var count=1;
var unbingWatch=$scope.$watch('todoList',function(){
  console.log('todoList change');
  count++;
  //相当于在todoList变化了4次之后,就调用unbingWatch()取消这个watch
  //在第5次todoList改变的时候,就不会输出todoList change了。
  if(count>4){
    unbingWatch();
  }
});

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

时间: 2017-08-10

浅谈Angular.js中使用$watch监听模型变化

$watch简单使用 $watch是一个scope函数,用于监听模型变化,当你的模型部分发生变化时它会通知你. $watch(watchExpression, listener, objectEquality); 每个参数的说明如下: watchExpression:监听的对象,它可以是一个angular表达式如'name',或函数如function(){return $scope.name}. listener:当watchExpression变化时会被调用的函数或者表达式,它接收3个参数:n

Angular中使用$watch监听object属性值的变化(详解)

Angular中的$watch可以监听属性值的变化,然后并做出相应处理. 常见用法: $scope.$watch("person", function(n, o){ //todo something... }) 但是对于一个对象中的某个属性值变化时,$watch似乎不管用了. 示例代码: <body> <div ng-controller="mainCtrl"> <input id="myText" type=&qu

AngularJS中的$watch(),$digest()和$apply()区分

AngularJS $scope里面的$watch(),$digest()和$apply()是AngularJS的核心函数,学习AngularJS必须理解这几个函数. 在绑定$scope中的变量到view的时候,AngularJS自动在内部创建一个"Watch"."Watch"用于监听AngularJS scope中变量的改变.可以通过调用$scope.$watch()这个方法来创建"Watch". $scope.$digest()函数会循环访问

关于angular js_$watch监控属性和对象详解

$Watch:(监听一个model,当一个model每次改变时,都会触发第二个函数) $watch('watchFn',watchAction,deepWatch) watchFn:带有Angular 表达式或者函数的字符串,它会返回被监控的数据模型的当前值. watchAction: 一个函数function(newValue,oldValue){},当watchFn 发生变化时会被调用 deepWatch:默认为false,监听数组的某个元素或者对象的属性时设置为true; 监控一个属性:

Angular中的$watch、$watchGroup、$watchCollection

•  1,原型:$watch: function(watchExp, listener, objectEquality, prettyPrintExpression){}: •  2,参数:watchExp(必须):{(function()|string)},可以字符串表达式,也可以带当前scope为参数的函数 • - `string`: Evaluated as {@link guide/expression expression} • - `function(scope)`: called

angular $watch 一个变量的变化(实例讲解)

废话不多说,直接上代码 $scope.$watch('custArea', function(newValue, oldValue) { angular.forEach(newValue, function(item, key) { if($scope.custArea.indexOf("000000") > -1){ // $scope.toastWarn("已选择中国大陆所有省市,其他值不可选"); $scope.custArea =["0000

AngularJS中watch监听用法分析

本文实例讲述了AngularJS中watch监听用法.分享给大家供大家参考,具体如下: ANGULAR 监听使用: 当angular数据模型发生变化时,我们需要如果需要根据他的变化触发其他的事件. $watch是一个scope函数,用于监听模型变化,当你的模型部分发生变化时它会通知你. $watch(watchExpression, listener, objectEquality); watchExpression 需要监控的表达式 listener 处理函数,函数参数如下  function

AngularJS中$apply方法和$watch方法用法总结

本文实例总结了AngularJS中$apply方法和$watch方法用法.分享给大家供大家参考,具体如下: 引言 最近在项目中封装控件的时候用到了$watch方法来监听module中的值的变化,当时小编对这个方法不是很了解,所以在网上找了一些资料来学习一下,下面小编就给大家简单介绍一些AngularJS中Scope 提供$apply 方法传播Model 的变化和$watch方法监听module变化. $apply使用情景 AngularJS 外部的控制器(DOM 事件.外部的回调函数如 jQue

AngularJS实现动态添加Option的方法

本文实例讲述了AngularJS实现动态添加Option的方法.分享给大家供大家参考,具体如下: 项目中后台管理设置,前台下拉动态添加option <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge&q

thinkphp3.x中display方法及show方法的用法实例

本文实例讲述了thinkphp3.x中display方法及show方法的用法.分享给大家供大家参考,具体如下: 通过前面的文章在了解了控制器和模型操作后,我们开始熟悉视图部分,ThinkPHP中的视图主要就是指模板文件和模板引擎,本篇首先了解下模板文件以及是如何进行渲染输出的. 一.模板定义 为了对模板文件更加有效的管理,ThinkPHP对模板文件进行目录划分,默认的模板文件定义规则是: 模板目录/[分组名/][模板主题/]模块名/操作名+模板后缀 模板目录默认是项目下面的Tpl, 当定义分组的

jQuery使用hide方法隐藏元素自身用法实例

本文实例讲述了jQuery使用hide方法隐藏元素自身用法,分享给大家供大家参考.具体如下: 下面的JS代码实现让按钮点击后将自己隐藏起来 <!DOCTYPE html> <html> <head> <script src="js/jquery.min.js"> </script> <script> $(document).ready(function(){ $("button").click(

Javascript call和apply区别及使用方法

一.方法的定义call方法: 语法:fun.call(thisArg[, arg1[, arg2[, ...]]])定义:调用一个对象的一个方法,以另一个对象替换当前对象.说明:call 方法可以用来代替另一个对象调用一个方法.call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisArg 指定的新对象.如果没有提供 thisArg参数,那么 Global 对象被用作 thisArg. apply方法:语法:fun.apply(thisArg[, argsArray])定义:应用某

javascript面向对象之共享成员属性与方法及prototype关键字用法

本文实例讲述了javascript面向对象之共享成员属性与方法及prototype关键字用法.分享给大家供大家参考.具体如下: 共享成员属性与方法,使用prototype关键词 复制代码 代码如下: <script language="javascript" type="text/javascript"> function Dog(){} Dog.prototype.shout=function(){  alert("hello,小狗"

jQuery的load()方法及其回调函数用法实例

本文实例讲述了jQuery的load()方法及其回调函数用法.分享给大家供大家参考.具体如下: 下面的js代码演示了jQuery的load()方法的使用,并演示了带回调函数(callback)的load方法的使用 <!DOCTYPE html> <html> <head> <script src="js/jquery.min.js"> </script> <script> $(document).ready(fun

AngularJS遍历获取数组元素的方法示例

本文实例讲述了AngularJS遍历获取数组元素的方法.分享给大家供大家参考,具体如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>获取数组的元素例子</title> <script src="angular.min.js"></script> <s

angularjs实现table增加tr的方法

需求: 上面是一个table,运用了 <tr ng-repeat="rule in formData.ruleList track by $index"> 循环显示.现在的一个需求是:需要在每行添加一个字段,不过不能在同一行显示,需要在下一行显示.我首先想到了直接加个,不过没有办法换行.在下面再加个也不行.只能依赖强大的angulajs,自定义指令.下面我们就开始. 1 自定义指令 .directive( 'kbnTableRow', function($compile)

angularJs 表格添加删除修改查询方法

如下所示: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="agl/angular.min.js"></script> <script> var app=angular.module("