Angular学习(十一)——$watch、模板数据的展现
2014-08-06 22:55
309 查看
将$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();
让我们来对购物卡场景进行重新设定。如果我们想对其中的打折优惠进行设定,然后我们就可以得到:
注意在代码最后,我们设定一个观察totalCart()的观察器。每当这个值发生变化时,这个监控器将会调用calculateDiscount(),我们将打折值设定为一个合适的值。
之前章节中我们遇到过很多详细设定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(),我们将打折值设定为一个合适的值。
相关文章推荐
- javascript学习笔记(十一)对表格进行排序(包括数值、字符串、日期等数据类型)
- 【android学习之十一】——数据存储3:数据共享ContentProvider,ContentResolver
- 一步步学习微软InfoPath2010和SP2010--第六章节--发布并提交表单数据(5)--管理员批准模板
- angular学习笔记(十四)-$watch(4)
- angular学习笔记(十一)-表达式
- Asp.net控件开发学习笔记(十一)----服务器控件模板
- iOS学习笔记(十一)——JSON数据解析
- Angular学习(7)- 模板
- 数据分析,展现与R语言学习笔记(1)
- C++学习笔记之由文本文件读取数据到vector模板建立的二维数组 并存储为新的文本文件
- Windows Phone 开发学习笔记(十一) RSS阅读器之显示数据
- windbg 学习----#(从反汇编中搜索符合指定模板的数据)
- iOS学习——JSON数据解析(十一)
- Angular学习(7)- 模板2
- oracle 学习笔记(十一) 数据库常用对象, table ,constraint ,index ,view和数据字典
- 转:C#数据结构和算法学习系列十一----构建字典DictionaryBase 类和SortedList 类
- WPF学习1 DataGrid 采用模板列进行数据绑定
- iOS学习笔记(十一)——JSON数据解析 (转)
- yii 学习笔记十、将通过模型获得的数据展现到视图模版中
- seajs学习日志 简单尝试模板+数据合并、模块异步加载、非标准CMD模式定义define模块