我生待明日,万事成蹉跎

AngularJS简单入门(4)—脏检查机制($apply、$digest、$watch)及购物车示例

AngularJS中是怎么知道变量是否发生变化呢?——靠的就是AngularJS的脏检查(只脏检查被绑定到html中的对象、属性)。这就涉及到$apply、$digest、$watch,需要注意的是:$apply只是进入angular context,然后通过$digest去触发脏检查,接着脏检查又会触发$watch,于是整个Angular双向绑定机制就活了起来。

下面通过小栗子了解Angula脏检查机制:
jishiqi

以下是源码:

</body>
<script type="text/javascript">
    angular.module("MyApp", [])
        .controller("MyController", function ($scope, $q) {
            //值虽改变,但没触发脏检查
            $scope.date=new Date();
          /* setInterval(function(){
               $scope.date=new Date();
           },1000);*/
            //1、apply  触发脏检查
            setInterval(function(){
                //apply里可以写函数或表达式
                $scope.$apply(function(){
                    $scope.date=new Date();
                })
            },1000);
        })
        .controller('Mycontroller2',function($scope){
            $scope.str1="默认值";
            $scope.tcount=0;
            //2、$watch 第一个参数也可为所监听的对象 监听一个model model每次改变时都会触发第二个函数   第三个可有可无
            $scope.$watch('str1',function(newval,olval){
                ++$scope.tcount;
                if($scope.tcount>10){
                    $scope.str1="大于10次不能改变了";
                }
            });
        });
</script>

 

1、$watch 监听一个model,model的value每次改变时都会触发第二个函数,第三个参数是布尔值可有可无

$scope.$watch('str1',function(newval,olval){
    ++$scope.tcount;
    if($scope.tcount>10){
        $scope.str1="大于10次不能改变了";
 }
});

2、$apply触发脏检查

$scope.$apply(function(){
                    $scope.date=new Date();
                })

 

下面再通过一个购物车示例来了解Angular脏检查机制($watch在源码最后部分):

GIF

<body style="padding:40px" ng-app="MyApp">
      <div class="container" ng-controller="carController">
          <table class="table table-striped" ng-show="cart.length">
              <thead>
              <tr>
                  <th>产品编号</th>
                  <th>产品名字</th>
                  <th>购买数量</th>
                  <th>产品单价</th>
                  <th>产品总价</th>
                  <th>操作</th>
              </tr>
              </thead>
              <tbody>
              <tr ng-repeat="m in cart">
                  <td>{{m.id}}</td>
                  <td>{{m.name}}</td>
                  <td>
                      <button type="button" ng-click="del(m.id)" class="btn btn-primary">-</button>
                      <input type="text" value="{{m.quantity}}" ng-model="m.quantity">
                      <button type="button" ng-click="add(m.id)" class="btn btn-primary">+</button>

                  </td>
                  <td>{{m.price}}</td>
                  <td>{{m.price * m.quantity}}</td>
                  <td>
                      <button type="button" class="btn btn-danger" ng-click="removeFunc(m.id)">移除</button>
                  </td>
              </tr>
              <tr>
                  <td>总购买价</td>
                  <td>{{totalPriceFunc()}}</td>
                  <td>总购买数量</td>
                  <td>{{totalnumFunc()}}</td>
                  <td colspan="2">
                      <button type="button" class="btn btn-danger" ng-click="cart={}">清空购物车</button>
                  </td>
              </tr>
              </tbody>
          </table>
          <p ng-show="!cart.length">购物车为空</p>
      </div>
</body>
<script type="text/javascript">
    angular.module("MyApp", [])
        .controller("carController", function ($scope) {
             $scope.cart=[
                 {
                     id:10,
                     name:"Tshirt",
                     quantity:3,
                     price:2300
                 },
                 {
                     id:20,
                     name:"iphone6s",
                     quantity:2,
                     price:5300
                 },
                 {
                     id:30,
                     name:"pingpong",
                     quantity:10,
                     price:30
                 },
                 {
                     id:40,
                     name:"football",
                     quantity:29,
                     price:460
                 }
             ];
            //总价:
            $scope.totalPriceFunc=function(){
                var totalprice=0;
                angular.forEach($scope.cart,function(im){
                    totalprice+=im.quantity*im.price;
                })
                return totalprice;
            };
            //总数量:
            $scope.totalnumFunc=function(){
                var totalnum=0;
                angular.forEach($scope.cart,function(im){
                    totalnum+=parseInt(im.quantity);
                })
                return totalnum;
            };
            //移除
            $scope.removeFunc=function(id){
                var index=-1;
                angular.forEach($scope.cart,function(m,thekey){
                    if(m.id===id){
                        index=thekey;
                        return;
                    }
                });
                if(index!==-1){//理论上讲 thekey的值一定能取到
                    $scope.cart.splice(index,1);//第一个参数:删除的起始下标  第二个参数:删除个数
                }
            }

            //数量的增减

                      //找到当前索引
                      var findIndex=function(id){
                          var index=-1;
                         angular.forEach($scope.cart,function(m,key){
                            if(m.id===id){
                                 index=key;
                                return;
                            }
                         });
                          return index;
                      }
                     //增加数量
                     $scope.add=function(id){
                         var theindex=findIndex(id);
                         if(theindex!==-1){
                             ++$scope.cart[theindex].quantity;
                         }
                     }
                     //减去数量
                      $scope.del=function(id){
                          var theindex=findIndex(id);
                          if(theindex!==-1){
                              var theshopNum=$scope.cart[theindex].quantity;//当前商品数量
                              if(theshopNum>1){
                                  --$scope.cart[theindex].quantity;
                              }else{
                                  var msg=confirm('是否从购物车删除该商品?');
                                  if(msg){
                                      $scope.removeFunc(id);
                                  }
                              }
                          }
                      }
            //自动脏检查(看输入框输入的数量是否符合要求)
            $scope.$watch('cart',function(newValue,oldValue){
                angular.forEach(newValue,function(m,index){
                    if(m.quantity<1){
                        var msg=confirm('是否从购物车删除该商品?');
                        if(msg){
                            $scope.removeFunc(m.id);
                        }else{
                            m.quantity=newValue[index].quantity;
                        }
                    }
                });
            },true);
        })
</script>

未经允许不得转载:徐宏涛博客 » AngularJS简单入门(4)—脏检查机制($apply、$digest、$watch)及购物车示例

分享到:更多 ()

评论 抢沙发

评论前必须登录!