Angular核心概念
(1)本质:设计动态web应用的结构框架。
web应用与传统web系统相区别,web应用能为用户提供丰富的操作,能够随用户操作不断更新视图而不进行url跳转。Angular官方也声明它更适用于开发CRUD应用,即数据操作比较多的应用
(2)核心:对HTML标签的增强
就是使你能够用标签完成一部分页面逻辑,具体方式就是通过自定义标签、自定义属性等,这些HTML原生没有的标签/属性在ng中有一个名字:指令。
(3)是MVC还是MVVM?
官网有提到ng的设计采用了MVC的基本思想,但它并不是MVC,因为在书写代码时确实是在用ng-controller这个指令,但这个controller处理的业务基本上都是与view进行交互,所以angular**更接近MVVM**。
简单介绍一下MVVM:即Model-View-ViewModel,它采用双向绑定(data-binding):View的变动,自动反映在 ViewModel,反之亦然。
具体MVC.MVP,MVVM的比较可以参考这篇博客:
http://www.ruanyifeng.com/blog/2015/02/mvcmvp_mvvm.html
(4)适用于?
AngularJS是一个MV* 框架,最适于开发客户端的单页面应用。如果你要开发的是单页应用,AngularJS就是你的上上之选。Gmail、Google Docs、Twitter和Facebook这样的应用,都很能发挥AngularJS的长处。但是像游戏开发之类对DOM进行大量操纵、又或者单纯需要 极高运行速度的应用,就不适合AngularJS了。
(5)工作原理
HTML模板将会被浏览器解析到DOM中, DOM结构成为AngularJS编译器的输入。AngularJS将会遍历DOM模板, 来生成相应的NG指令,所有的指令都负责针对view(即HTML中的ng-model)来设置数据绑定。因此, NG框架是在DOM加载完成之后, 才开始起作用的.
(6)优点
1.引入了依赖注入与双向绑定,不需写大量代码就能实现复杂功能
2.不用像jquery操作复杂的dom代码,只需要改变数据模型就可以
Angular重要特性
(1)数据双向绑定
一个web应用可能包含了80%的代码用来处理,查询和监听DOM。数据绑定使得代码极大的减少,开发者可以更专注于应用的数据交互方面。
在我们使用jQuery的时候,代码中会大量充斥类似这样的语句:var val = (‘#id’).val();(‘#id’).html(str);等等,即频繁的DOM操作(读取和写入),其实我们的最终目的并不是要操作DOM,而是要实现业务逻辑。ng的绑定将让你摆脱DOM操作,只要模板与数据通过声明进行了绑定,两者将随时保持同步,最新的数据会实时显示在页面中,页面中用户修改的数据也会实时被记录在数据模型中。
什么是数据双向绑定?
HTML中呈现的view与AngularJS中的数据是一致的. 修改其一, 则对应的另一端也会相应地发生变化.
下面是一个简单的数据双向绑定的例子(通过ng-app 、 ng-model 和 { {msg } } ):
<body ng-app="app">
<!--绑定下面js定义的controller,MyController的管理边界就是这个div-->
<div ng-controller="MyCtroller">
<!-- 将变量通过{{}}绑定到html中-->
<h1>{{msg}}</h1>
<!-- 通过ng-model也可以绑定模型到html-->
<input type="text" ng-model="msg"/>
</div>
<script>
angular.module('app',[])//定义module,[]里是它的变量名
.controller('MyCtroller',function($scope){ //定义控制器,器名,$scope是应用程序所指向的html元素
$scope.msg="angular";//6.对scope定义一个变量名
})
</script>
双向绑定原理:
AngularJS**在$scope变量中使用脏值检查来实现了数据双向绑定。和Ember.js数据双向绑定中动态设施setter和getter不同,脏治检查允许AngularJS监视那些存在或者不存在的变量。**
最简单的说法,50ms为一个心跳,去判断一个controller里所有对象的变化,如果有变化,那么更新相关的元素
详细原理可以参考这篇博客:AngularJS 数据双向绑定揭秘:http://sentsin.com/web/779.html
(2)依赖注入(DI)
什么是依赖注入?
wiki 上的解释是:依赖注入(Dependency Injection,简称DI)是一种软件设计模式,在这种模式下,一个或更多的依赖(或服务)被注入(或者通过引用传递)到一个独立的对象(或客户端)中,然后成为了该客户端状态的一部分。
该模式分离了客户端依赖本身行为的创建,这使得程序设计变得松耦合,并遵循了依赖反转和单一职责原则。与服务定位器模式形成直接对比的是,它允许客户端了解客户端如何使用该系统找到依赖
一句话 — 没事你不要来找我,有事我会去找你。
AngularJS 提供很好的依赖注入机制。以下5个核心组件用来作为依赖注入:
value:一个简单的 javascript 对象,用于向控制器传递值(配置阶段)
factory:一个函数用于返回值。在 service 和 controller 需要时创建。通常我们使用 factory 函数来计算或返回值。
service
provider:AngularJS 中通过 provider 创建一个 service、factory等(配置阶段)。Provider 中提供了一个 factory 方法 get(),它用于返回 value/service/factory
constant:constant(常量)用来在配置阶段传递数值,注意这个常量在配置阶段是不可用的。
mainApp.constant("configParam", "constant value");
详细的定义方式可参考:http://www.runoob.com/angularjs/angularjs-dependency-injection.html
AngularJS中service,factory,provider的区别可参考:
http://my.oschina.net/tanweijie/blog/295067
通过依赖注入,ng想要推崇一种声明式的开发方式,即当我们需要使用某一模块或服务时,不需要关心此模块内部如何实现,只需声明一下就可以使用了。在多处使用只需进行多次声明,大大提高可复用性。
比如我们的controller,在定义的时候用到一个$scope
参数。
app.controller('testC',function($scope){});
如果我们在此处还需操作其他的东西,比如与浏览器地址栏进行交互。我们只需再多添
一个参数$location
进去:
app.controller('testC',function($scope,$location){});
这样便可以通过$location
来与地址栏进行交互了,我们仅仅是声明了一下,所需的其他代码,框架已经帮我们注入了
。我们很明显的感觉到了这个函数已经不是常规意义上的javascript函数了,在常规的函数中,把形参换一个名字照样可以运行,但在此处若是把$scope换成别的名字,程序便不能运行了。因为这是已经定义好的服务名称。
这便是依赖注入机制。顺理成章的推断,我们可以自己定义模块和服务,然后在需要的地方进行声明,由框架来替我们注入。
来看下如何定义一个服务:
app.factory('tpls',function(){
return ['tpl1','tpl2','tpl3','tpl4'];
});
看上去相当简单,是因为我在这里仅仅是直接返回一个数组。在实际应用中,这里应该是需要向服务器发起一个请求,来获取到这些模板们。服务的定义方式有好几种,包括使用provider方法、使用factory方法,使用service方法。它们之间的区别暂且不关心。我们现在只要能创建一个服务出来就可以了。我使用了factory方法。一个需要注意的地方是,框架提供的服务名字都是由$
开头的,所以我们自己定义的最好不要用$开头,防止发生命名冲突。
定义好一个服务后,我们就可以在控制器中声明使用了,如下:
app.controller('testC',function($scope,tpls){
$scope.question = questionModel;
$scope.nowTime = new Date().valueOf();
$scope.templates = tpls; //赋值到$scope中
$scope.addOption = function(){
var o = {content:''};
$scope.question.options.push(o);
};
$scope.delOption = function(index){
$scope.question.options.splice(index,1);
};
});
此时,若在模板中书写如下代码,我们便可以获取到服务tpls所提供的数据了:
模板:
<a href="javascript:void(0);" target="_blank" rel="nofollow">
AngularJS常用指令整理
1.ng-app: 初始化一个 AngularJS 应用程序。
2.ng-init: 初始化应用程序数据。
3.ng-model: 把数据模型元素值(比如输入域的值)绑定到应用程序。
4.ng-repeat:循环输出指定次数的 HTML 元素,集合必须是数组或对象。
5.ng-controller:绑定控制器。
6.ng-if与ng-show/hide:都是控制dom元素的显示或隐藏,ng-if指令根据表达式的值在DOM中生成或移除一个元素(false为移除,反之生成),ng-show/hide只是隐藏或显示,不移除。
7.ng-submit:在表单提交后执行指定函数。
8.ng-disabled:设置表单输入字段的disabled属性(input, select, 或textarea),ng-disabled中的表达式返回 true 则表单字段被禁用。
9.ng-checked:设置复选框(checkbox)或单选按钮(radio)的 checked 属性, 该属性返回 true,复选框(checkbox)或单选按钮(radio)将被选中。
10.ng-src:绑定文件资源路径
11.ng-href:覆盖原生的 <a> 元素 href 属性。如果在 href 的值中有 AngularJS 代码,则需要使用 ng-href 而非 href。ng-href 指令确保了链接是正常的,即使在 AngularJS 执行代码前点击链接。
12.ng-class:给 HTML 元素动态绑定一个或多个 CSS 类。
13.ng-selected:设置<select>列表中的<option>元素的selected属性,ng-selected属性的表达式返回true则选项被选中
14.ng-change:ng-change 指令用于告诉 AngularJS 在 HTML 元素值改变时需要执行的操作,需要搭配 ng-model 指令使用,不会覆盖原生的 onchange 事件, 如果触发该事件,ng-change 表达式与原生的 onchange 事件都执行。
下面通过一个完整的实例实践一下ng指令:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>AngularJS指令</title>
<link rel="stylesheet" href="css/foundation.min.css">
<script src="js/angular.min.js"></script>
<script src="js/js-AngularJS-04-Instructions.js"></script>
<style type="text/css">
.tx {
width: 100px;
height: 100px;
}
</style>
</head>
<!--1.ng-app 初始化一个 AngularJS 应用程序-->
<body ng-app="myapp">
<!--2.ng-controller 绑定controller-->
<div ng-controller="UserController">
<!--11.ng-submit 在表单提交后执行指定函数-->
<form action="#" name="f" ng-submit="register(user)">
<fieldset>
<legend>用户信息</legend>
<!--4.ng-src 绑定文件资源路径,需加{{}}-->
<!--5.ng-class 给HTML元素动态绑定一个或多个CSS类,前面是样式class名,写在上面的style中,后面的是true就渲染该样式-->
<!--6. ng-if与ng-show/hide(""里为结果是true或false的值):都是控制dom元素的显示或隐藏(if: false为移除,反之生成显示)而ng-show/hide只是隐藏或显示,不移除-->
<img ng-src="{{user.img}}"
ng-class="{'tx':user.showicon}"
ng-if="user.isShow">
<div>
姓名
<!--3.ng-model 绑定数据模型-->
<input type="text" ng-model="user.uname" required>
<!--7.ng-checked 设置复选框(checkbox)或单选按钮(radio)的checked属性, 该属性返回 true,复选框(checkbox)或单选按钮(radio)将被选中-->
性别(单选按钮):
<input type="radio"
ng-checked="user.sex=='1'"
name="sex">男
<input type="radio"
ng-checked="user.sex=='0'"
name="sex">女
<br>
兴趣(复选框):
<!--9. ng- 的属性值既可以是值,表达式,也可以为函数,通过函数处理的结果的返回值来做属性值,常用的一种技巧-->
<input type="checkbox" ng-checked="isChecked(1)">音乐
<input type="checkbox" ng-checked="isChecked(2)">电影
<input type="checkbox" ng-checked="isChecked(3)">体育
<input type="checkbox" ng-checked="isChecked(4)">旅游
<br>
<!--8.ng-selected 设置<select>列表中的<option>元素的selected属性,ng-selected属性的表达式返回true则选项被选中-->
职位:
<select name="" id="">
<option value="0" ng-selected="user.job=='0'">--请选择--</option>
<option value="1" ng-selected="user.job=='1'">前端</option>
<option value="2" ng-selected="user.job=='2'">运维</option>
</select>
<!--10.ng-disabled 设置表单输入字段的disabled属性(input, select, 或textarea,button都可以用),ng-disabled中的表达式返回true则表单字段被禁用
表单里的姓名input里加了required属性,如果不填,按钮会变灰无法提交(这里是用了angular内置的一个属性(元素名.$invalid)得到元素的可用性)-->
<button type="submit" class="button expand"
ng-disabled="f.$invalid">
提交
</button>
</div>
</fieldset>
</form>
<div>
<ui class="ul-list ui-list-link ui-list-text ui-list-active ui-border-tb">
<!--12. ng-repeat 循环输出指定次数的 HTML 元素,集合必须是数组或对象
三个内置常用属性:$index(下标从零开始) $first $last-->
<li ng-repeat="a in list1" class="ui-border-t">
<h3>{{$index+1+':'+a.title+' '+$first+' '+$last}}</h3>
</li>
</ui>
</div>
</div>
</body>
</html>
所引用的js文件:js-AngularJS-04-Instructions.js
/**
* Created by chenhaoact on 16/3/14.
*/
angular.module('myapp', []) //1.定义app
.controller('UserController', function ($scope) { //2.定义controller
//3.controller中新建对象或变量,常量等
$scope.user = {
uname: ' 安卓',
pwd: '',
sex: '1',
job: '1',
hobby: [1, 2, 3],
img: 'img/android.png',
showicon: true,
isShow: true
};
//4.定义isChecked函数,结合isChecked属性,通过数组控制多选框的选择情况
//5.ng- 的属性值既可以是值,表达式,也可以为函数,通过函数处理的结果的返回值来做属性值,常用的一种技巧
$scope.isChecked = function (n) { //n是页面传回来的值
var isok = false;
for (var i = 0; i < $scope.user.hobby.length; i++) {
if (n == $scope.user.hobby[i]) {
isok = true;
break;
}
}
return isok; //注意函数return的位置
}
$scope.register = function (u) {
console.log(u); //从页面得到了输入的对象,这样就可以进行各种处理
}
//在页面中可通过 ng-repeat 循环输出指定次数的 HTML 元素,集合必须是数组或对象
$scope.list1 = [
{title: '标题1',info: 11},
{title: '标题2',info: 22},
{title: '标题3',info: 33},
{title: '标题4',info: 44}
];
});
Angular实现原理
1双向绑定原理
Angular的数据观测采用的是脏检查(dirty checking)机制。每一个指令都会有一个对应的用来观测数据的对象,叫做watcher;一个作用域中会有很多个watcher。每当界面需要更新时,Angular会遍历当前作用域里的所有watcher,对它们一一求值,然后和之前保存的旧值进行比较。如果求值的结果变化了,就触发对应的更新,这个过程叫做digest cycle。
脏检查有两个问题:
任何数据变动都意味着当前作用域的每一个watcher需要被重新求值,因此当watcher的数量庞大时,应用的性能就不可避免地受到影响,并且很难优化。
当数据变动时,框架并不能主动侦测到变化的发生,需要手动触发digest cycle才能触发相应的DOM 更新。Angular通过在DOM事件处理函数中自动触发digest cycle部分规避了这个问题,但还是有很多情况需要用户手动进行触发。
对于这个问题,Vue.js给出了不一样的解决方法:基于依赖收集的观测机制,有兴趣的话可以研究一下Vue.js。
AngularJS常用插件收集
1 图片视频类
angular-maxonry 图片墙效果插件,可以将图片组织成类似于瀑布流的效果,依赖于jQuery、imageloaded和Masonry
angular-deckgrid 另一个照片瀑布流解决方案
ngImgCrop 图片剪裁工具
ngVideo 播放器,直接播放指定地址的mp4,控制按钮美观度远甩朝内99.99%的视频站
2 输入控件类
ngDraggable 控制元素拖动的控件,Demo
angular-umeditor 百度umeditor的AngularJS扩展,umeditor从界面上讲并不够现代化,但却总有人喜欢它
ngAutocomplete 喜闻乐见的自动补完
textAngular 文本编辑器,更简洁,更漂亮
ngTagsInput 以标签的方式来组织输入
Angular-slider 以拖动方式输入值的控件
Angular Slidezilla 与Angular-slider功能一样,只不过设计风格不一样
3 界面类
ui-bootstrap 官方扩展,在AngularJS中方便的以指令的方式使用Bootstrap
ui-map 用于在页面中集成Google Maps
NG-Grid 官方提供的表格插件,支持表格的主题、排序、直接编辑、多行选择等操作,而且使用非常简单,只需要一行HTML代码,但是,比较难看,适合于不讲究外观但要求功能强大的场合,像后台工具、管理系统之类
angular-table 第三方表格工具,适合于需要对表格进行高度定制的场合
ng-table 在易用性和外观上对上面两个进行折衷的解决方案
AngularUI 上面的ui-bootstrap、ui-map就是它的一部分,官方提供的常用扩展集,除了这两个,还有ui-router、ui-select等,注意,它使用的是Bootstrap 2.x
Adapt-Strap 第三方Bootstrap插件,而且是基于扁平化的Bootstrap 3,更美观
ng-polymer-elements Polymer风格的AngularJS指令,Material Design设计,值得尝试
Angular Loading Bar 可用于在页面顶部增加一个漂亮的进度条
angular-busy 与Angular Loading Bar有点类似,主要用于处理
http通信时候的动画ngInfiniteScroll从名字可以看出来,它是一个用于组织瀑布流和时间线的扩展ngScrollTo页内滚动工具,可以将页面滚动到指定id的元素位置ngDialog比Bootstrap更简单,更好用,更漂亮的网页对话框AngularTreeview树状目录组织扩展,使用相当方便,而且不依赖于jQueryangular−growl用于在页面上显示警告框,可以设置显示时间,还可以直接显示
http中收到的警告
angular-truncate 当文字过多过长时,显示部分文字的插件,可以按文字总长度来控制,也可以按单词数量来控制
4 调试工具
Batarang:专门为angular设计的一款调试工具,在chrome插件中心可以进行安装
5 其它工具类
angular-translate AngularJS的i18n扩展
Satellizer 可以方便的在AngularJS中集成第三方账号登陆,支持国际主流社交网站账号,支持协议有OAuth 1.0/2.0
ngStorage 本在存储插件,用于处理localStorage和sessionStorage
ng-csv 导出csv的扩展
三 AngularJS学习资源
(1)AngularJS官网:https://angularjs.org/