以下是归档内容,来自2015年angular学习笔记。学习自慕课网大漠穷秋。虽然已经过去了好久,但仍然记得老师当时的思路多清晰。棒棒哒。
angular的4大核心特性
MVC,模块化,指令系统,双向数据绑定是angular的四个最主要的核心特性。
MVC
什么是MVC,M数据模型,V视图层,负责展示,C业务逻辑和控制逻辑。职责清晰,代码模块化。
为什么要用MVC?
一定要理解这句话:MVC这是手段,终极目标是模块化和复用。不是因为要去实现MVC才去做东西,是因为要要去模块化和复用才去用MVC的。
代码规模越来越大,切分职责是大势所趋
为了复用:很多逻辑是一模一样的
为了后期维护方便,修改一块功能不影响其他的功能。
前端MVC的困难?
浏览器加载js文件是要分成两段的,一段是下载,一段是执行,由于下面的一些问题,导致了前端MVC的实现不想后台那么方便。
浏览器加载脚本–>加载完成后JIT编译执行。
操作DOM的代码必须等整个页面加载完成
多个JS文件之间如果出现互相依赖,程序猿必须自己解决
js的原型继承也给前端编程带来了很多困难。
关于C(controller)
通过ng-controller指令来实现控制器。
下面会将下面这种方法来声明控制器是不好的,因为没有实现模块化。1
2
3
4
5function hello($scope){
$scope.textInput = {
text:"cailidan"
};
}
MVC–controller的实现方式1
这样第一种的实现方式并不好,因为如果视图1和视图2并没有任何逻辑关系,控制器的角色就会很尴尬。也不符合我们代码的分离。无法应对大项目。
MVC–controller的实现方式2
这样是一种改进型的方法,我们把视图1和视图2的控制器分开,分别控制。但是如果我们视图1和视图2有两个一模一样的方法怎么办?就出现了下面的方式3.
MVC–controller的实现方式3
看起来时一种好方法,我们让控制器1和2继承这个公用控制器。但这种方法是不可以实行的。这在angular中是不允许,不可行的,不推荐的。
MVC–controller的实现方式4
通过sevice来做,把通用的东西抽象成服务,让控制器调用,而不是来继承这个通用控制器。
Controller使用过程中的注意点
不要试图去复用Controller,一般一个控制器只负责一小块试图
不要在Controller中操作DOM,这不是controller的职责
不要在Controller中做数据格式化,ng有很好用的表单
不要在Controller里面做数据过滤,ng有$filter服务来过滤数据
一般来说,Controller是不会互相调用的,控制器之间的交互会通过事件进行。
对上面的几点的稍微解释:控制器是把业务逻辑放进去,业务逻辑一般不会大段大段的相同。操作DOM时指令的工作,而不是控制器的工作。数据过滤和数据格式化都可以用angular自己的服务和控件。Controller不要相互调用,否则耦合性太强。
关于数据模型MODEL
首先找ng-app,找到后,里面所有的东西归angular管,然后找这里面所有的指令编译。比如找到了ng-modal,这是挂在rootscope,在ng-app下面的任意一个都可以获得。
虽然上面的例子不是angular推荐的,主要看内部的$scope里面的设置。这就是主要实现modal的方法。
模块化
不推荐的写法:1
2
3
4
5function hello($scope){
$scope.textInput = {
text:"cailidan"
};
}
这样定义了很多很多的全局函数,肯定是不好的,而通过定义一个模块,然后在模块上生成控制器,这是angular的实现模块方法。注意写法,[“$scope”,function()]。1
2
3
4
5
6
7
8
9var myModule = angular.module("myModule",[]);
myModule.directive("hello",function(){
return {
restrict:"E",
template:"<div>cailidan</div>",
replace:true
}
})
angular一切都是从模块开始的,只有把模块定义好了,才能够在模块上调用service,controller,filter等等。就是首先就是定义模块。
指令系统
下面这个代码中,如果再html中写了hello就会被替换成cailidan。ng-app实际上就是angular的一个指令,相当于main。在任何一个单页中ng-app只能出现一次。
1 | var myModule = angular.module("myModule",[]); |
上面也是一种如何复用View的方法。我们可以定义很多个不用的指令,然后在需要他们地方加载他们,这样也就达到了复用模板的目的。
双向数据绑定
单项数据绑定
目前大多数前端框架都是实现单向数据绑定,jqueryUI,BackBone,Flex。单向数据绑定的过程是:首先是把模板写好,然后加上数据,数据可能是从后台读出来的。把模板和数据绑定在一起,生成html标签,然后插入到模板中,这样不好的地方是,html一旦生成完后就没法变了,当有新的数据来时,只能重新绑定生成。所以angular就实现了双向事件绑定。
双向数据绑定
核心想法是:视图和模型是对应的,当数据模型发生变化的时候,它希望视图自动更新,当视图发生变化的时候,数据模型也发生变化。这中间需要一种时间机制。比如表单中,视图会自动变化,当表单的视图发生变化时,就可以自动反应到数据模型。下面是一个实例。
1 | <body ng-app> |
双大括号是用来取值的。当input里面发生变化时,ng-modal的值也会发生变化。
具体的$scope解释
angularJS的MVC都是通过作用域$scope实现的。
看下这个$scope能实现什么。
1 | function GreetCtrl($scope,$rootScope){ |
这里$rootScope就是根作用域,整个的作用域就像一个树形结构一样。1
2
3
4
5
6
7
8
9
10<div ng-controller="GreetCtrl">
Hello{{name}}
</div>
<div ng-controller="ListCtrl">
<ol>
<li ng-repeat = "name in names">
{{name}} from {{department}}
</li>
</ol>
</div>
这里的department虽然不是在ListCtrl中定义的,但由于是全局作用域,所以根目录下所有的模块都能访问到。跟作用域链有点像,如果再自己的$scope里面没有,就一直往上找,一直到$rootScope为止。
可以用插件来看到$scope的树形结构。
$scope的生命周期
首先是创建一个$scope,然后是注册一个监控,然后检测模型变化,然后观察模型,最后销毁(自动或手动)。