angularjs UI控制其分离,scope应用及$watch观察模型变化

   在上一节讲完了关于应用开发中如数据绑定,添加样式一类的基础操作后,接下来,将在应用中,与控制其有关的一些事件。。。


一、UI和控制器的分离

我们需要明确控制器在应用中的三个作用:

【1】在应用模型中设置初始状态

【2】通过$scope对象向视图(UI模版)暴露函数和模型

【3】监视模型发生变化的其他部分并做出相应的动作


二、发布scope中的数据模型

 传递给控制器的$scope对象是一种用来向视图暴露模型数据的机制。在我们构建的应用中可能有其他数据,但是通过scope传递这些属性时,angular只考虑模型部分。

 在之前的荔枝中,我们经常看到$scope构建的数据实例,而这一过程是在控制器中完成,在这里,我们也可以通过一些间接的方法从模版建立模型。


1.使用表达式:由于表达式在可它们关联的控制器中执行,所以在表达式中设置属性和控制器中设置属性是一致的。即可以如下这么做

<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进行一个数据绑定


三、用$watch观察模型变化

$watch(watchFn, watchAction, deepWatch)
该函数每个参数详细内容

watchFn:这个参数是angualr表达式字符串或返回监控模型的当前值的函数。

watchAction:这是一个函数或者表达式,当watchFn变化时将调用他们。它有watchFn的心新旧值及一个scope引用,函数签名function(newValue,oldValue,scope);

deepWatch:这是一个可选的布尔参数,如果设置成true,angualr将检查在被监视对象中每个属性的每次变化。如果希望监视数组中私有元素或者对象中的属性,而不是仅仅一个简单的值的时候,便可使用该参数。

这里结合之前的一个购物车的荔枝进行简单的分析

<div ng-controller="CartController">
<div ng-repeat="item in items">
<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>

CartController代码:

function CartController($scope) {
$scope.bill = {};
$scope.items = [
{title: 'Paint pots', quantity: 8, price: 3.95},
{title: 'Polka dots', quantity: 17, price: 12.95},
{title: 'Pebbles', quantity: 5, price: 6.95}
];
$scope.totalCart = function() {
var total = 0;
for (var i = 0, len = $scope.items.length; 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);
}

CartController控制器末尾,我们在totalCart()上面建立了一个监视,而totalCart()是用于计算付款总额,每当这个值发生变化时,watch函数便会调用其后面的calculateDiscount(),然后进行相应的操作。



Watch()性能注意事项

而在上述的荔枝中有个小小的问题,当你在totalCart()加一个调试断点,你会看到它被调用了六次以后才渲染到页面;

而这六次分别是:

1.模版的{{totalCart|currency}}

2.SubTotal()函数

3.$watch()函数

 而在这三次基础之上,angular自身会再运行它们一次,以便验证传递的模型变化已经完全传递,模型已经不再变化。

对与这样多次调用可能造成的潜在问题,我们有以下的几种方法去解决;

【1】在数组中的每个元素上创建$watch监控变化,这样仅仅需要重新去计算total,discount和subtotal.

为了实现这个点,我们可以用以下几种方法来更新模版

<div>Total: {{bill.total | currency}}</div>
<div>Discount: {{bill.discount | currency}}</div>
<div>Subtotal: {{bill.subtotal | currency}}</div>

然后在js中我们监视数组中的元素,数组发生任何变化都会调用函数重新计算总值。

function CartController($scope) {
$scope.bill = {};
$scope.items = [
{title: 'Paint pots', quantity: 8, price: 3.95},
{title: 'Polka dots', quantity: 17, price: 12.95},
{title: 'Pebbles', quantity: 5, price: 6.95}
];
var calculateTotals = function() {
var total = 0;
for (var i = 0, len = $scope.items.length; i < len; i++) {
total = total + $scope.items[i].price * $scope.items[i].quantity;
}
$scope.bill.totalCart = total;
$scope.bill.discount = total > 100 ? 10 : 0;
$scope.bill.subtotal = total - $scope.bill.discount;
};
$scope.$watch('items', calculateTotals, true);
}

在这里我们看到$watch指定了一个items字符串,这是可以的,并且该字符串将作为表达式在调用它的$scope作用域中执行


四、组织模块依赖


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值