Angular学习(十一)——$watch、模板数据的展现

本文深入探讨Angular中的数据绑定机制,介绍如何通过scope将数据发布到模板,并使用$watch观察模型变化。讲解了$watch函数的使用,包括其参数含义和应用场景,以及如何有效地管理观察器。
摘要由CSDN通过智能技术生成

    将$scope对象传递给控制器的一种机制可以使模板数据发布到相应的视图。在应用中可能还有其他的数据,但是Angular仅在这些数据能够通过一个scope控制这些属性时才将其认为是模板的一部分。你可以将scope想象成一个用来为模板观察者做出相应改变的上下文环境。

    之前章节中我们遇到过很多详细设定scope的案例,比如$scope.count = 5;同样也有一些间接的方式来将Model设定成模板。可以采用如下的方式来完成这些:

    1、通过一个表达式。因为表达式在控制器的scope上下文环境中的执行与其相应的元素相关,在表达式中设置器属性值等同于在一个控制器的scope中设置器属性。比如:

    <button ng-click="count=3">Set count to three</button>

    这种方式等同于:

    <div ng-controller="CountController">

         <button ng-click="setCount()">Set count to three</button>

    </div>

    function CountController($scope){

        $scope.setCount = function(){

             $scope.count=3;

        }

    }

    2、通过在一个输入控件中使用ng-model。就像表达式一样,作为ng-model参数的特定Model同样在封闭控制器的scope之内。这样所产生的附带效应是它会在空间区域状态和你所特定Model之间产生一个双向数据绑定。

Observing Model Changes with $watch

    在所有的作用域函数中,最常用的函数就是$scope。$scope可以通知用户当前模型哪一个部分改变了。你可以观察单个的对象属性、计算结果(或函数)和任何可以作为一个属性或者作为Javascript函数来执行的所有对象。这个函数的原型是:

        $watch(watchFn, watchAction, deepWatch)

其三个参数的含义分别为:

    watchFn:这个参数是一个带有Angular表达式或一个返回观测模型当前值的函数的字符串。这个表达式将会被多次评估,所以在使用之前必须确认该表达式没有任何副作用。也就是说,这个表达式在被多次调用后也不会改变其状态。这是由于这个原因,观测表达式的效率应该会比较低。如果你将一个Angular表达式传入一个字符串,它将会评估对象对于其调用作用域的可用性。

    watchAction:这个是当watchFn改变时所要调用的函数或表达式。在函数控件中,它将收到watchFn的一个原值和新值以及一个作用域的引用。它的原型是function(newValue, oldValue, scope)

    deepWatch:如果设置为TRUE,这个可选的布尔参数将会通知Angular去检查观测对象的每一个属性的改变。如果你想查看一个数组或一个对象中的所有属性的一个元素而不是简单的一个值时,可以设置这个参数为TRUE。因为Angular需要去遍历这个数组或对象,所以当集合内元素很多时,这产生很大的消耗。

    $watch函数返回一个函数,这个函数将会在你不再想接收改变通知时重新注册监听器。如果你想去检测一个属性,然后在对其重新注册,我们将会使用如下的方式:

      ...... 

       var dereg = $scope.$watch("someModel.someProperty", callbackOnChange());

     ...... dereg();

    让我们来对购物卡场景进行重新设定。如果我们想对其中的打折优惠进行设定,然后我们就可以得到:

<script src="angular.min.js"></script>
<div ng-controller="CartController">
	<h1>Your Order</h1>
	<div ng-repeat="item in items">
		<span>{{$index+1}}</span>
		<span>{{item.title}}</span>
		<input ng-model="item.quantity">
		<span>{{item.price | currency}}</span>
		<span>{{item.price * item.quantity | currency}}</span>
		
	</div>
	<div>Total : {{totalCart() | currency}}</div>
	<div>Discount:{{bill.discount |currency}}</div>
	<div>Subtotal:{{subtotal() |currency}}</div>
</div>
	<script>
	function CartController($scope){
	        $scope.bill = {};
			$scope.items = [
				{title:"Paint pots",quantity:8,price:3.95},
				{title:"Polka dots",quantity:5,price:12.95},
				{title:"Pebbles",quantity:5,price:6.95},
			];
			$scope.totalCart =function(){
				var total = 0;
				var len = $scope.items.length
				for(var i = 0;i < len;i++){
					total = total + $scope.items[i].price * $scope.items[i].quantity;
				}
				return total;
			}
			$scope.subtotal = function(){
				return $scope.totalCart() - $scope.bill.discount;
			};
			function calculateDiscount(newValue,oldValue,scope){
				$scope.bill.discount = newValue > 100 ? 10 : 0;
			}
			
			$scope.$watch($scope.totalCart, calculateDiscount);
		}
	</script>

注意在代码最后,我们设定一个观察totalCart()的观察器。每当这个值发生变化时,这个监控器将会调用calculateDiscount(),我们将打折值设定为一个合适的值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值