发表于: 2017-01-11 22:10:51
1 1223
一、今天完成的事情:
1.继续刷angular,自己做了几个小demo
2.搞清了在什么时候要手动使用$apply,告诉angular我需要他帮我看这里的数据是否修改了。
二、明天要做的事情:
1.继续巩固基础,并且写小demo
2.着手完成任务8,感觉我基本的积累已经能够完成任务8了,任务9应该问题不大
3.仔细学习正则,今天只在高程上过了一遍。
三、遇到的问题:
今天主要整理了一下apply方面和异步方面的知识,异步还没有怎么搞懂,先放一部分apply的出来:
- 首先我们要知道什么叫双向数据绑定,双向数据绑定指的是,view层上的改变会影响到scope上的数据上,同样的scope上的改变也会反应到view上。这两个操作意味着,scope模型会自动的更新!这是怎么实现的呢:当你写出{{}}的时候,angular会在你上面的数据中给你加上一个watcher,这种方法和你在js中写下的$watch是一样的!所以watch是什么??
- $scope.$watch('aModel', function(newValue, oldValue) {
- //update the DOM with newValue
- });
- 传入watch中的第二个参数是一个回调函数,这个回调函数会用来更新更新view。但是这个东西他是怎么知道我们的modle发生了变化呢?这就要说道$digest了
- 在$digest循环中,watch会被触发,当一个watch被触发时,angulajs就会去检查scope模型,如果模型发生了变化,那么绑定在这个watch中的回调函数就会被触发。。。。。。。。那么digest循环是在什么时候以何种方式被触发呢?
- 这个问题的答案是:当你调用了$scope.$digest()之后,digest循环就被触发了。。。那么问题来了我们应该如何触发$scope.$digest呢?比如你在使用ng-click调用函数删除了scope里的一条数据之后,digest就被触发了!他触发之后,会触发每一个watcher,这些watcher会检查现在的值和上一次得出的值是否相等,如果不相等,他会自动调用回调函数!除了ngclick指令,还有built-in指令以及服务来让你更改models(ng-nodle、$timeout等)会自动触发一次digest循环!
- 在我上面说的这些东西之中,angularjs并不直接调用$digest,而是调用$scope.$apply,在后续的函数中会调用$rootScope.$digest(),所以,循环开始时会调用$rootScope.$digest(),然后会访问到你所有的child-scope中的watchers。。。。。这段话的意思是什么呢?接下来我们举个例子。
- 看我这一行代码:
<button type="button" ng-click="remove(item.id)" class="btn btn-primary btn-xs">删除</button>
在这一行代码中,我们可以看到我将ng-click绑定了一个方法,当这个button被点击的时候,angular会将此function包装在一个wrapping function中,传入到$scope.$apply()中,如果它这个里面有改变modole的话,接下来会触发$rootScope.$digest,来改变view里对应的东西!这里补充一个小note:我们的$apply有两种形式,第一种是传入一个function,并触发一次$degist循环,第二种是没有任何传入,直接执行一次digest循环!这两种方法第一种会优于第二种! - 什么时候需要我们手动调用&apply:angular对于自动加入appy有明确的规定:他只会对上下文环境中的更改自动进行加入操作,如果在上下文之后进行了更改,我们就必须要手动的告诉angular,帮我们触发一下循环!相当于告诉angular说我这里的modle发生了更改,麻烦你帮我自动更新到view上去!接下来我们举个例子:
如果我们在页面载入两秒中后,更改页面中显示的东西myApp.controller("list",function ($scope) {
//$scope.num = 80; //双向绑定
$scope.getmessage=function () {
setTimeout(function () {
$scope.message = "这是两秒钟后显示的东西";
console.log("提示信息已更改为 "+$scope.message);
},2000);
}
$scope.getmessage();
});
如果像我上面这样做,那么我们的控制台之中会打印出已更改,但是view中并不会有任何的变化,这就是因为我们在上下文环境之外对它进行了改变!接下来让我们更改一下,提醒一下angular帮我们检测一下是否已被更改!myApp.controller("list",function ($scope) {
//$scope.num = 80; //双向绑定
$scope.getmessage=function () {
setTimeout(function () {
$scope.$apply(function () { //提醒anglar,我之后要做的事情会改变modle(在上下文之外)帮我触发apply
$scope.message = "这是两秒钟后显示的东西";
console.log("提示信息已更改为 "+$scope.message);
})
},2000);
};
$scope.getmessage();
});
如果像上面这样做,angular就会知道,这个东西会改变modle,我需要为它触发一个$digest!当然这个还有一个写法,就是在第一种方法最下面加上$scop.apply(),但是这种不会触发angular的错误检查机制,让angular不会做到正确的错误排查,所以我们每次使用的时候,都必须给apply传入一个参数!! - 接下来还有一个问题 $digest会被执行多少次?$digest循环不会只执行一次,上面我们说到,apply会触发$digest循环,然后$digest循环会触发所有的watcher当watcher发现里面的modle发生了变化,他就自动调用回调函数,将view上的响应东西一起改变。但是如果我们在这个回调函数中也修改了modle的值呢?那么就要说到angular里的另一个检查机制---脏检查,所以它会一直执行到model不再变化或者循环的次数达到了10次。。。所以我们尽可能的不要在watch的回调函数中去修改modle的值!
- 根据我们上面说的,$digest至少也会运行两次,多运行一次是为了保证modle确实没有发生变化
- 最后划个重点:我的理解是:如果你改变modle的行为脱离了上下文,那么这种行为就不会自动的被angular加入到apply中去,就需要你手动告诉angular,嘿!这个东西已经被我修改了!你帮我传到view里面去一下!
- 这里我又想到了几个问题:
- watch如何单独使用?
- 上下文到底是个什么东西?什么时候才算是脱离了上下文
交给大家一起乱来探讨思考一下吧~
今天大师兄讲了angular的controller,controller里主要放是业务逻辑和大型的代码,业务逻辑是什么呢?业务逻辑就是你这个应用,比如说是一个购物网站,消费者可以选择他要什么商品,选择了商品之后可以进行付款,付款的时候余额不足就提示他 余额不足,要是成功了就提醒成功购买。。
评论