Angular中的$watch、$watchGroup、$watchCollection


Posted in Javascript onJune 25, 2017

•  1,原型:$watch: function(watchExp, listener, objectEquality, prettyPrintExpression){};

•  2,参数:watchExp(必须):{(function()|string)},可以字符串表达式,也可以带当前scope为参数的函数

- `string`: Evaluated as {@link guide/expression expression}

- `function(scope)`: called with current `scope` as a parameter.

• 3,参数:listener(必须):function(newVal, oldVal, scope),观察的表达式变化的时候调用的函数。

• 4,参数:objectEquality(非必须):是否监视个对象,默认为false

• 5,$scope.$digest().会执行所有的同$scope下的$watch。

但会出错$apply already in progress,换了$rootScope也一样。

原因-参考大牛博客:http://blog.csdn.net/aitangyong/article/details/48972643

$digest、$apply、$$phase这些属性或者方法其实都是$scope中的私有的,最好不要使用。

• 6,$watch一个对象。

如果要监视对象的变化(地址改变),$watch对象名,第三个参数默认;

如果监测对象中某一属性,可以写user.name的形式,第三个参数默认;

如果监测对象中全部属性,$watch对象名,第三个参数true;

• 7,$watchGroup,第一个参数是一个表达式的数组或者返回表达式的数组的函数。

• 8,$watchCollection;

js中数组也是对象,但按照$watch一个对象的方式,只有数组引用变了才能监听变化,增加删除$watch监听不到,所以就有了$watchCollection。

function(obj, listener):第一个参数必须对象或者返回对象的函数。

•9,注销$watch

       $watch函数返回一个注销监听的函数,太多的$watch将会导致性能问题,$watch如果不再使用,我们最好将其释放掉。

一、使用方法

html

<div ng-controller="ctrl">
    <h2>$watch</h2>
    <div>
      <input type="text" ng-model="value1"/>
    </div>
    <div ng-bind="w1"></div>
    <h2>$watchGroup</h2>
    <div>
      <input type="text" ng-model="value2"/>
      <input type="text" ng-model="value3"/>
    </div>
    <div ng-bind="w2"></div>
    <h2>$watchCollection</h2>
    <ul>
      <li ng-repeat="v in arr" ng-bind="v"></li>
    </ul>
    <div ng-bind="w3"></div>
  </div>

js

angular.module('nickApp', [])
        .controller("ctrl", ["$scope", "$timeout", function ($scope, $timeout) {
          // $watch
          var watcher = $scope.$watch("value1", function (newVal, oldVal) {
            $scope.w1 = "$watch--" + "new:" + newVal + ";" + "old:" + oldVal;
            if (newVal == 'clear') {//设置一个注销监听的条件
              watcher(); //注销监听
            }
          });
          // $watchGroup
          $scope.$watchGroup(["value2", "value3"], function (newVal, oldVal) {
            //注意:newVal与oldVal都返回的是一个数组
            $scope.w2 = "$watchGroup--" + "new:" + newVal + ";" + "old:" + oldVal;
          });
          //  $watchCollection
          $scope.arr = ['nick', 'ljy', 'ljj', 'zhw'];
          $scope.$watchCollection('arr', function (newVal, oldVal) {
            $scope.w3 = "$watchCollection--" + "new:" + newVal + ";" + "old:" + oldVal;
          });
          $timeout(function () {
            $scope.arr = ['my', 'name', 'is', 'nick'];
          }, 2000);
        }])

二、小案例

html

<h2>小案例</h2>
  <ul>
    <li ng-repeat="item in items.goodsArr">
      <p ng-bind="item.goods"></p>
      <p>
        <span>单价:</span>
        <span ng-bind="item.price"></span>
      </p>
      <div>
        <input type="number" ng-model="item.num">
        <span>个</span>
      </div>
    </li>
  </ul>
  <div>
    <span>总计:</span>
    <span ng-bind="items.sum"></span>
    <span>元</span>
  </div>

js          

//     小案例
        .factory('watchService', [function () {
          var items = {
            goodsArr: [{
              goods: 'goods1',
              price: 10,
              num: ''
            }, {
              goods: 'goods2',
              price: 20,
              num: ''
            }],
            sum: 0
          };
          return {
            getItemsSave: function () {
              return items;
            }
          };
        }])
        .controller('bodyCtl', ['$scope', 'watchService', function ($scope, watchService) {
          $scope.items = watchService.getItemsSave();
//          这里要监听数量变化计算综合
          //一 只监听所有num变化计算总额
          var watchArr = [];
          $scope.items.goodsArr.forEach(function (v, i) {
            watchArr.push("items.goodsArr[" + i + "]['num']");
          });
          $scope.$watchGroup(watchArr, function (newVal, oldVal) { //注意:newVal与oldVal都返回的是一个数组
            $scope.items.sum = 0;
            $scope.items.goodsArr.forEach(function (v, i) {
              $scope.items.sum += v.price * (v.num > 0 ? v.num : 0);
            });
          });
/*
          //二 这样写则监听items.goodsArr所有成员
          $scope.$watch('items.goodsArr', function () {
            $scope.items.sum = 0;
            $scope.items.goodsArr.forEach(function (v, i) {
              $scope.items.sum += v.price * (v.num > 0 ? v.num : 0);
            });
          }, true);*/
        }])

全部代码

<!DOCTYPE html>
<html ng-app="nickApp">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
  <title>angular之$watch、$watchGroup、$watchCollection</title>
  <script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script>
  <script>
    /*
     * 1,原型:$watch: function(watchExp, listener, objectEquality, prettyPrintExpression){};
     * 2,参数:watchExp(必须):{(function()|string)},可以字符串表达式,也可以带当前scope为参数的函数
     *    - `string`: Evaluated as {@link guide/expression expression}
     *    - `function(scope)`: called with current `scope` as a parameter.
     * 3,参数:listener(必须):function(newVal, oldVal, scope),观察的表达式变化的时候调用的函数。
     * 4,参数:objectEquality(非必须):是否监视个对象,默认为false
     * 5,$scope.$digest().会执行所有的同$scope下的$watch。
     *  但会出错$apply already in progress,换了$rootScope也一样。
     *  原因-参考大牛博客:http://blog.csdn.net/aitangyong/article/details/48972643
     *  $digest、$apply、$$phase这些属性或者方法其实都是$scope中的私有的,最好不要使用。
     * 6,$watch一个对象。
     *  如果要监视对象的变化(地址改变),$watch对象名,第三个参数默认;
     *  如果监测对象中某一属性,可以写user.name的形式,第三个参数默认;
     *  如果监测对象中全部属性,$watch对象名,第三个参数true;
     * 7,$watchGroup,第一个参数是一个表达式的数组或者返回表达式的数组的函数。
     * 8,$watchCollection;
     *   js中数组也是对象,但按照$watch一个对象的方式,只有数组引用变了才能监听变化,增加删除$watch监听不到,所以就有了$watchCollection。
     *   function(obj, listener):第一个参数必须对象或者返回对象的函数。
     */
    angular.module('nickApp', [])
        .controller("ctrl", ["$scope", "$timeout", function ($scope, $timeout) {
          // $watch
          var watcher = $scope.$watch("value1", function (newVal, oldVal) {
            $scope.w1 = "$watch--" + "new:" + newVal + ";" + "old:" + oldVal;
            /*
             *注销$watch
             *太多的$watch将会导致性能问题,$watch如果不再使用,我们最好将其释放掉。
             *$watch函数返回一个注销监听的函数,如果我们想监控一个属性,然后在稍后注销它,可以使用下面的方式:
             */
            if (newVal == 'clear') {//设置一个注销监听的条件
              watcher(); //注销监听
            }
          });
          // $watchGroup
          $scope.$watchGroup(["value2", "value3"], function (newVal, oldVal) {
            //注意:newVal与oldVal都返回的是一个数组
            $scope.w2 = "$watchGroup--" + "new:" + newVal + ";" + "old:" + oldVal;
          });
          //  $watchCollection
          $scope.arr = ['nick', 'ljy', 'ljj', 'zhw'];
          $scope.$watchCollection('arr', function (newVal, oldVal) {
            $scope.w3 = "$watchCollection--" + "new:" + newVal + ";" + "old:" + oldVal;
          });
          $timeout(function () {
            $scope.arr = ['my', 'name', 'is', 'nick'];
          }, 2000);
        }])
        //     小案例
        .factory('watchService', [function () {
          var items = {
            goodsArr: [{
              goods: 'goods1',
              price: 10,
              num: ''
            }, {
              goods: 'goods2',
              price: 20,
              num: ''
            }],
            sum: 0
          };
          return {
            getItemsSave: function () {
              return items;
            }
          };
        }])
        .controller('bodyCtl', ['$scope', 'watchService', function ($scope, watchService) {
          $scope.items = watchService.getItemsSave();
//          这里要监听数量变化计算综合
          //一 只监听所有num变化计算总额
          var watchArr = [];
          $scope.items.goodsArr.forEach(function (v, i) {
            watchArr.push("items.goodsArr[" + i + "]['num']");
          });
          $scope.$watchGroup(watchArr, function (newVal, oldVal) { //注意:newVal与oldVal都返回的是一个数组
            $scope.items.sum = 0;
            $scope.items.goodsArr.forEach(function (v, i) {
              $scope.items.sum += v.price * (v.num > 0 ? v.num : 0);
            });
          });
/*
          //二 这样写则监听items.goodsArr所有成员
          $scope.$watch('items.goodsArr', function () {
            $scope.items.sum = 0;
            $scope.items.goodsArr.forEach(function (v, i) {
              $scope.items.sum += v.price * (v.num > 0 ? v.num : 0);
            });
          }, true);*/
        }])
  </script>
</head>
<body ng-controller="bodyCtl">
<div ng-view>
  <div ng-controller="ctrl">
    <h2>$watch</h2>
    <div>
      <input type="text" ng-model="value1"/>
    </div>
    <div ng-bind="w1"></div>
    <h2>$watchGroup</h2>
    <div>
      <input type="text" ng-model="value2"/>
      <input type="text" ng-model="value3"/>
    </div>
    <div ng-bind="w2"></div>
    <h2>$watchCollection</h2>
    <ul>
      <li ng-repeat="v in arr" ng-bind="v"></li>
    </ul>
    <div ng-bind="w3"></div>
  </div>
  <h2>小案例</h2>
  <ul>
    <li ng-repeat="item in items.goodsArr">
      <p ng-bind="item.goods"></p>
      <p>
        <span>单价:</span>
        <span ng-bind="item.price"></span>
      </p>
      <div>
        <input type="number" ng-model="item.num">
        <span>个</span>
      </div>
    </li>
  </ul>
  <div>
    <span>总计:</span>
    <span ng-bind="items.sum"></span>
    <span>元</span>
  </div>
</div>
</body>
</html>

以上所述是小编给大家介绍的Angular中的$watch、$watchGroup、$watchCollection,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

Javascript 相关文章推荐
可自己添加html的伪弹出框实现代码
Sep 08 Javascript
js 判断控件获得焦点的示例代码
Mar 04 Javascript
jquery 实现input输入什么div图层显示什么
Jun 15 Javascript
jquery实现上下左右滑动的方法
Feb 09 Javascript
详解JavaScript中jQuery和Ajax以及JSONP的联合使用
Aug 13 Javascript
超详细的javascript数组方法汇总
Nov 21 Javascript
javascript的正则匹配方法学习
Feb 24 Javascript
JS 组件系列之BootstrapTable的treegrid功能
Jun 16 Javascript
Vue 自定义指令功能完整实例
Sep 17 Javascript
jenkins自动构建发布vue项目的方法步骤
Jan 04 Vue.js
原生JS实现音乐播放器
Jan 26 Javascript
Vue项目中如何封装axios(统一管理http请求)
May 02 Vue.js
JS实现加载时锁定HTML页面元素的方法
Jun 24 #Javascript
Angular2.js实现表单验证详解
Jun 23 #Javascript
JS实现多张图片预览同步上传功能
Jun 23 #Javascript
Vue组件化通讯的实例代码
Jun 23 #Javascript
JavaScript字符串检索字符的方法
Jun 23 #Javascript
Angular2 组件通信的实例代码
Jun 23 #Javascript
js实现文字列表无缝滚动效果
Jun 23 #Javascript
You might like
一些需要禁用的PHP危险函数(disable_functions)
2012/02/23 PHP
php中$_POST与php://input的区别实例分析
2015/01/07 PHP
ThinkPHP5 验证器的具体使用
2018/05/31 PHP
Laravel框架使用Seeder实现自动填充数据功能
2018/06/13 PHP
PHP使用PhpSpreadsheet操作Excel实例详解
2020/03/26 PHP
JSON扫盲帖 JSON.as类教程
2009/02/16 Javascript
ext checkboxgroup 回填数据解决
2009/08/21 Javascript
将字符串转换成gb2312或者utf-8编码的参数(js版)
2013/04/10 Javascript
javascript 中that的含义示例介绍
2014/05/14 Javascript
JavaScript中toString()方法的使用详解
2015/06/05 Javascript
学习使用AngularJS文件上传控件
2016/02/16 Javascript
JavaScript中0和&quot;&quot;比较引发的问题
2016/05/26 Javascript
jQuery实现的自定义滚动条实例详解
2016/09/20 Javascript
jQuery实现下拉菜单的实例代码
2017/06/19 jQuery
在 Angular 中使用Chart.js 和 ng2-charts的示例代码
2017/08/17 Javascript
Vue过滤器,生命周期函数和vue-resource简单介绍
2021/01/12 Vue.js
[01:19]2014DOTA2国际邀请赛 采访TITAN战队ohaiyo 能赢DK很幸运
2014/07/12 DOTA
[01:19:54]DOTA2上海特级锦标赛主赛事日 - 2 败者组第二轮#1Alliance VS EHOME
2016/03/03 DOTA
[01:17:47]TNC vs VGJ.S 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
[41:13]完美世界DOTA2联赛PWL S2 Forest vs Rebirth 第一场 11.20
2020/11/20 DOTA
对于Python异常处理慎用“except:pass”建议
2015/04/02 Python
python3.5实现socket通讯示例(TCP)
2017/02/07 Python
用Python3创建httpServer的简单方法
2018/06/04 Python
Python面向对象思想与应用入门教程【类与对象】
2019/04/12 Python
Python3 利用face_recognition实现人脸识别的方法
2020/03/13 Python
基于python检查矩阵计算结果
2020/05/21 Python
用python实现一个简单计算器(完整DEMO)
2020/10/14 Python
Python logging自定义字段输出及打印颜色
2020/11/30 Python
canvas需要在标签里直接定义宽高
2014/12/17 HTML / CSS
全球性的奢侈品梦工厂:Forzieri(福喜利)
2019/02/20 全球购物
室内设计专业学生的自我评价分享
2013/11/27 职场文书
学校周年庆活动方案
2014/08/22 职场文书
旅游活动总结
2014/08/27 职场文书
房产授权委托书范本
2014/09/22 职场文书
2016年大学生暑假爱心支教活动策划书
2015/11/26 职场文书
【海涛七七解说】DCG第二周:DK VS 天禄
2022/04/01 DOTA