angular学习(1)

简介

angular js是一个MVVM框架,通过ng-app指令定义一个angular js的应用程序,
AngularJS 模块(Module) 定义了 AngularJS 应用。
AngularJS 控制器(Controller) 用于控制 AngularJS 应用。
ng-app指令指明了应用, ng-controller 指明了控制器。
ng-model来进行双向绑定
表达式可以写在双大括号内

1
{{}}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<body ng-app="LoginModel" ng-controller="LoginCtrl">
<script>
var app = angular.module('LoginModel', []); //可以通过依赖注入来注入服务
app.controller('LoginCtrl', function($scope,httpService) {
$scope.firstName= "John";
$scope.lastName= "Doe";
});
</script>
//定义http公共服务
//定义公有的http服务
LoginModel.factory("httpService",
function ($http, $q) {
return {
post: function (suburl, params) {
var defer = $q.defer();
$http({
method: 'POST',
params: params,
url: "http://dodo.hznu.edu.cn/" + suburl,
}).success(function (data) {
if (data.retcode == 0) {
defer.resolve(data.items);
}
else
defer.reject(data.message);
}).error(function (data) {
defer.reject(data);
});
return defer.promise;
},

$scope是当前的控制域,在当前控制域当中可以获得双向绑定的一些值和定义函数ng-click,ng-model等

1
2
3
4
$scope.user = {};
$scope.submit = function() {

}

angular js脏检查机制

监控对象的属性
$watch和$digest是相辅相成的,两者构成了angular作用域的核心,数据变化的响应

原理:

angular在scope模型上设置了一个一个监听队列,用来监听数据变化并且更新view,每次绑定一个东西
到view上的时候,angular 就会往$watch队列中插入一个$watch,用来检测他监控的model里面是否有变化的东西,
当浏览器接收到可以被angular context处理的事件时,$digest循环就会触发,遍历所有的$watch,最后更新dom.

$watch绑定要检查的值
当一个作用域创建的时候,angular会去解析模板中当前作用域下的模板结构,并且自动将插值,

1
2
{{text}}
ng-click = "update"

找出来,利用$watch建立绑定,并且push到当前作用域上的$$watcher队列
当使用$wacth绑定了要检查的属性之后,当这个属性值发生变化了,触发$digest循环,angular会去遍历这个数组,并且用$dirty去记录$$watcher里面记录的哪些$scope的属性值发生变化,当有变化的时候,dirty设置为true,一轮脏检查执行完,会再检查dirty,如果dirty为true的话,会再次调用自己,知道dirty为true.但是为了防止死循环,一般设置当递归发生了10次或者以上,直接抛出一个错误,并且跳出循环。
当递归流程执行完,$digest还将变化后的$scope重新渲染到界面,$apply函数

脏检查的实现:

bind(),apply(),$scope构造函数以及构造函数的原型方法$watch(),$digest()
实现的四步骤
1.实现数据的单向绑定
2.实现$watch()监听数据变化
3.实现$digest()循环遍历每一个watch对象
4.实例化$scope

触发脏检查时间

只有当UI事件,ajax请求或者timeout延迟事件,才会触发脏检查
angular 每一个绑定到UI的数据,都有一个$watch对象,

双向数据绑定

界面到数据的修改,是由ajax,UI事件,或者timeout等回调事件来做。
数据到界面的呈现是由脏检查机制来做的。

参考博客
掘金链接
angularjs常用函数:$apply,$watch和$digest
$digest是一个内部函数,正常的代码都是无法应用到的,想要主动触发他,就要调用scope.$apply函数,是触发angularjs”脏检查机制”的常用公开接口,$digest循环包括2个while循环,分别是,处理$evalAsync的异步运算队列,处理$watch的watchers队列,当该循环触发后,会遍历当前$scope及其所有的子$scope上已经注册的所有watcher函数,遍历一遍所有的watcher被称为一轮脏检查,执行完一轮脏检查后,如果任何一个watcher所监听的值改变了,就会重新再进行一轮脏检查,直到所有的函数都报告其所监听的值都不再改变了。当循环结束后,才把模型的变化结果更新到DOM上去,这样做是为了防止频繁的更新。
表达式,angularjs不仅会渲染该数据,还会为这个值创建创建一个观察序列,之后,只要程序发生了任何事情,angularjs就会检查该观察过程中的值是否发生了修改,如果有,重新呈现表达式,运行这些观察者的过程称为脏检查。

angular2 双向绑定机制

angularjs是由$scope.apply()和$scope.digest触发,angular2接入了Zonejs,监听所有的异步事件,zonejs重写了所有的异步API,
监听异步api,当异步api发生变化,通知angular以组件树的形式进行检查。
zonejs会通知angularjs可能有数据发生变化,需要检测更新。
脏检查就是存储变量所有的值,每当可能的值发生变化的时候,将所有变量的旧值和新值进行比较,不相等就更新视图。

angular js采用脏检查。而angular的核心是组件化,组件的嵌套会形成一棵树。angular的变化检测可以按组件进行,每个组件有相应的变化检测器changeDetector,可想而知,这些变化检测器也会构成一棵树。
angular数据流是自顶向下的,从父组件到子组件单向流动。单向数据流向保证了高效、可预测的变化检测,尽管检查了负组件之后,自组件可能会改变父组件的数据使得父组件需要再次被检查,这是不被推荐的数据处理方式。在开发模式下,Angular会进行二次检查,如果出现上述情况,二次检查就会报错:ExpressionChangedAfterItHasBeenCheckedError(关于这个问题的答案,可以在参考资料中找到)。而在生产环境中,脏检查只会执行一次。

vue js与angular js区别

vue js更加灵活,比起angular更少专制,能够按照自己想要的方式构建应用,而非凡事都得按照vue的方法。它只不过是一层界面而已,因此你可以拿它作为页面中一个轻量的功能来使用,而不是一个完整的 SPA。
vue 仅仅是一个view层,只是一个如jquery搬的工具库,而angular是一个mvvm框架。
vue 使用数据劫持,object.defineProperty来实现,angular使用自己实现的一套模板编译规则。”脏检查机制”,来实现。相对来说vue性能更高。
vue 需要提供一个el对象并且进行实例化,后续所有作用范围都在el对象之下,而angular是整个html页面,一个页面,可以有多个vue实例,而angular不是这样的。

angular常见面试题

链接1
链接2