发表于: 2017-04-26 21:23:28
1 993
今天完成的事情:
给进度表格添加angularjs代码,并进行数据绑定,使用$http上传图片。
并查看理解$watch ,$apply 和 $digest --- 理解数据绑定过程。
明天计划的事情:
学习指令,试着把图片上传过程封装成一个组件,写任务10需要的页面,学习正则表达式。
遇到的问题:
1、上传图片时,进度表格里面的数据没有更新,后来知道是因为用的onchange事件,这是js的事件,它没有跟angular的数据同步,之后在函数中调用了$appy,然后就好了。
2、把formdata传给服务器的时候总是提示500,到现在都不知道为啥。
收获:
$watch ,$apply 和 $digest --- 理解数据绑定过程
我们的浏览器一直在等待事件,比如用户交互。假如点击一个按钮或者在输入框里输入东西,事件的回调函数就会在javascript解释器里执行,然后就可以做任何DOM操作,等回调函数执行完毕时,浏览器就会相应地对DOM做出变化。 Angular拓展了这个事件循环,生成一个成为angular context的执行环境。
$watch 队列($watch list):
每次绑定一些东西到UI上时你就会往$watch队列里插入一条$watch。想象一下$watch就是那个可以检测它监视的model里有变化的东西。每一个绑定到了UI上的数据都会生成一个$watch。当模版加载完毕时,也就是在linking阶段(Angular分为compile阶段和linking阶段),Angular解释器会寻找每个directive,然后生成每个需要的$watch。
$digest循环:
当浏览器接收到可以被angular context处理的事件时,$digest循环就会触发。这个循环是由两个更小的循环组合起来的。一个处理evalAsync队列,另一个处理$watch队列, 这个是处理什么的呢?$digest将会遍历我们的$watch,然后询问:
l 嘿,$watch,你的值是什么?
是9。
l 好的,它改变过吗?
没有,先生。
l (这个变量没变过,那下一个)
l 你呢,你的值是多少?
报告,是Foo。
l 刚才改变过没?
改变过,刚才是Bar。
l (很好,我们有DOM需要更新了)
l 继续询问知道$watch队列都检查过。
这就是所谓的dirty-checking。既然所有的$watch都检查完了,那就要问了:有没有$watch更新过?如果有至少一个更新过,这个循环就会再次触发,直到所有的$watch都没有变化。这样就能够保证每个model都已经不会再变化。如果循环超过10次的话,它将会抛出一个异常,防止无限循环。 当$digest循环结束时,DOM相应地变化。
这里很重要的是每一个进入angular context的事件都会执行一个$digest循环,也就是说每次输入一个字母循环都会检查整个页面的所有$watch。例如:
{{ name }}<button ng-click="changeFoo()">Change the name</button>
app.controller('MainCtrl', function() {
$scope.name = "Foo";
$scope.changeFoo = function() {
$scope.name = "Bar";
}});
通过$apply来进入angular context:
当事件触发时,调用$apply,它会进入angular context,如果没有调用就不会进入。因此上面的例子点击带有ng-click的元素时,事件就会被封装到一个$apply调用。如果有一个ng-model="foo"的输入框,然后敲一个f,事件就会这样调用$apply("foo = 'f';")
Angular什么时候不会自动为我们调用$apply呢?
为什么jQuery不会更新我绑定的东西呢?因为jQuery没有调用$apply,事件没有进入angular context,$digest循环永远没有执行。这种情况下就要执行$apply,如: scope.$apply();
$apply是$scope(或者是direcvie里的link函数中的scope)的一个函数,调用它会强制一次$digest循环(除非当前正在执行循环,这种情况下会抛出一个异常,这是我们不需要在那里执行$apply的标志)。
使用$watch来监视你自己的东西
你已经知道了我们设置的任何绑定都有一个它自己的$watch,当需要时更新DOM,但是我们如果要自定义自己的watches呢?例如:
app.controller('MainCtrl', function($scope) {
$scope.name = "Angular";
$scope.updated = -1;
$scope.$watch('name', function() {
$scope.updated++;
});});
<body ng-controller="MainCtrl">
<input ng-model="name" />
Name updated: {{updated}} times.</body>
这就是创造一个新的$watch的方法。第一个参数是一个字符串或者函数,在这里是只是一个字符串,就是要监视的变量的名字,在这里,$scope.name(注意只需要用name)。第二个参数是当$watch说监视的表达式发生变化后要执行的。我们要知道的第一件事就是当controller执行到这个$watch时,它会立即执行一次,因此我们设置updated为-1。
评论