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 相关文章推荐
JavaScript更改class和id的方法
Oct 10 Javascript
javascript代码运行不出来执行错误的可能情况整理
Oct 18 Javascript
js抽奖实现随机抽奖代码效果
Dec 02 Javascript
windows8.1+iis8.5下安装node.js开发环境
Dec 12 Javascript
jQuery的几个我们必须了解的特点
May 03 Javascript
原生js实现addClass,removeClass,hasClass方法
Apr 27 Javascript
jQuery实现6位数字密码输入框
Dec 29 Javascript
详解Vue中的基本语法和常用指令
Jul 23 Javascript
Angular8基础应用之表单及其验证
Aug 11 Javascript
微信小程序swiper使用网络图片不显示问题解决
Dec 13 Javascript
jQuery表单校验插件validator使用方法详解
Feb 18 jQuery
vue中使用带隐藏文本信息的图片、图片水印的方法
Apr 24 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读取和编写XML DOM的实现代码
2011/02/03 PHP
Laravel框架表单验证详解
2014/09/04 PHP
php为字符串前后添加指定数量字符的方法
2015/05/04 PHP
PHP使用ODBC连接数据库的方法
2015/07/18 PHP
jquery验证表单中的单选与多选实例
2013/08/18 Javascript
分享20款美化网站的 jQuery Lightbox 灯箱插件
2014/10/10 Javascript
js实现类似于add(1)(2)(3)调用方式的方法
2015/03/04 Javascript
Angular.js中$apply()和$digest()的深入理解
2016/10/13 Javascript
对layui中表单元素的使用详解
2018/08/15 Javascript
使用JavaScript计算前一天和后一天的思路详解
2019/12/20 Javascript
jquery将信息遍历到界面上实例代码
2020/01/21 jQuery
JS内置对象和Math对象知识点详解
2020/04/03 Javascript
Vue Element校验validate的实例
2020/09/21 Javascript
[09:43]DOTA2每周TOP10 精彩击杀集锦vol.5
2014/06/25 DOTA
Python中的元类编程入门指引
2015/04/15 Python
分析Python中设计模式之Decorator装饰器模式的要点
2016/03/02 Python
Python 实现数据库更新脚本的生成方法
2017/07/09 Python
Python算法之求n个节点不同二叉树个数
2017/10/27 Python
TensorFlow实现简单卷积神经网络
2018/05/24 Python
python中scikit-learn机器代码实例
2018/08/05 Python
Python实现的统计文章单词次数功能示例
2019/07/08 Python
python实现高斯判别分析算法的例子
2019/12/09 Python
python安装cx_Oracle和wxPython的方法
2020/09/14 Python
python 使用csv模块读写csv格式文件的示例
2020/12/02 Python
详解Python中的文件操作
2021/01/14 Python
全球最大的网上自行车商店:Chain Reaction Cycles
2016/12/02 全球购物
Speedo速比涛德国官方网站:世界领先的泳装品牌
2019/08/26 全球购物
世界上最伟大的马产品:Equiderma
2020/01/07 全球购物
电大物流学生的自我评价
2013/10/25 职场文书
总务岗位职责
2013/11/19 职场文书
劳资专员岗位职责
2013/12/27 职场文书
乡镇总工会学雷锋活动总结
2014/03/01 职场文书
新年抽奖获奖感言
2014/03/02 职场文书
勤奋学习演讲稿
2014/05/10 职场文书
大学毕业论文致谢词
2015/05/14 职场文书
保护动物的宣传语
2015/07/13 职场文书