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 相关文章推荐
用jQuery简化JavaScript开发分析
Feb 19 Javascript
JavaScript中常见陷阱小结
Apr 27 Javascript
JS自定义功能函数实现动态添加网址参数修改网址参数值
Aug 02 Javascript
js获取触发事件元素在整个网页中的绝对坐标(示例代码)
Dec 13 Javascript
JQuery与JS里submit()的区别示例介绍
Feb 17 Javascript
jQuery拖动div、移动div、弹出层实现原理及示例
Apr 08 Javascript
8个超实用的jQuery功能代码分享
Jan 08 Javascript
Bootstrap table简单使用总结
Feb 15 Javascript
浅析JS中常用类型转换及运算符表达式
Jul 23 Javascript
Vue 组件封装 并使用 NPM 发布的教程
Sep 30 Javascript
在layui下对元素进行事件绑定的实例
Sep 06 Javascript
vue-property-decorator用法详解
Dec 12 Javascript
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操作Access类(PHP+ODBC+Access)
2007/01/02 PHP
php中使用Curl、socket、file_get_contents三种方法POST提交数据
2011/08/12 PHP
总结PHP删除字符串最后一个字符的三种方法
2016/08/30 PHP
深入解析PHP中SESSION反序列化机制
2017/03/01 PHP
php判断目录存在的简单方法
2019/09/26 PHP
Ajax,UTF-8还是GB2312 eval 还是execScript
2008/11/13 Javascript
javascript 特性检测并非浏览器检测
2010/01/15 Javascript
javascript游戏开发之《三国志曹操传》零部件开发(三)情景对话中仿打字机输出文字
2013/01/23 Javascript
wap浏览自动跳转到wap页面的js代码
2014/05/17 Javascript
js实现网页自动刷新可制作节日倒计时效果
2014/05/27 Javascript
js实现在同一窗口浏览图片
2014/09/17 Javascript
jQuery实现单击和鼠标感应事件
2015/02/01 Javascript
jQuery拖拽插件gridster使用指南
2015/04/21 Javascript
JS判断字符串包含的方法
2015/05/05 Javascript
jQuery实现的网页换肤效果示例
2016/09/20 Javascript
Bootstrap fileinput文件上传组件使用详解
2017/06/06 Javascript
javascript定时器取消定时器及优化方法
2017/07/08 Javascript
简单的Vue SSR的示例代码
2018/01/12 Javascript
Vue+webpack+Element 兼容问题总结(小结)
2018/08/16 Javascript
JavaScript日期库date-fn.js使用方法解析
2020/09/09 Javascript
举例讲解Python面相对象编程中对象的属性与类的方法
2016/01/19 Python
python if not in 多条件判断代码
2016/09/21 Python
Python SQLite3数据库日期与时间常见函数用法分析
2017/08/14 Python
Python中一行和多行import模块问题
2018/04/01 Python
matplotlib subplots 设置总图的标题方法
2018/05/25 Python
python3 logging日志封装实例
2020/04/08 Python
Python selenium模块实现定位过程解析
2020/07/09 Python
运动鞋、足球鞋和慕尼黑球衣:Sport Münzinger
2019/08/26 全球购物
伦敦鲜花递送:Flower Station
2021/02/03 全球购物
幼儿园教师培训制度
2014/01/16 职场文书
三年级上册科学教学计划
2015/01/21 职场文书
德能勤绩廉个人总结
2015/02/14 职场文书
2016年春季趣味运动会开幕词
2016/03/04 职场文书
酒店工程部的岗位职责汇总大全
2019/10/23 职场文书
Python排序算法之插入排序及其优化方案详解
2021/06/11 Python
MySQL中正则表达式(REGEXP)使用详解
2022/07/07 MySQL