AngularJS
第1章介绍
AngularJS是一款由Google公司开发维护的前端MVC框架,其克服了HTML在构建应用上的诸多不足,从而降低了开发成本提升了开发效率。
1.1 特点
AngularJS与我们之前学习的jQuery是有一定的区别的,jQuery更准确来说只一个类库(类库指的是一系列函数的集合)以DOM做为驱动(核心),而AngularJS则一个框架(诸多类库的集合)以数据和逻辑做为驱动(核心)。
框架对开发的流程和模式做了约束,开发者遵照约束进行开发,更注重的实际的业务逻辑。
AngularJS有着诸多特性,最为核心的是:模块化、双向数据绑定、语义化标签、依赖注入等。
与之类似的框架还有BackBone、KnockoutJS、Vue、React等。
1.2 下载
1、通过AngularJS官网下载,不过由于国内特殊的国情,需要FQ才能访问。
2、通过npm下载,npm install angular
3、通过bower下载,bower install angular
bower是什么?
1.3 体验AngularJS
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>AngularJS 介绍</title><!-- 引入AngularJS 框架 --><script src="./libs/angular.min.js"></script></head><body ng-app><input type="text" ng-model="msg"><h2>你好: {{msg}}</h2></body></html>
1.4 MVC
MVC是一种开发模式,由模型(Model)、视图(View)、控制器(Controller)3部分构成,采用这种开发模式为合理组织代码提供了方便、降低了代码间的耦合度、功能结构清晰可见。
模型(Model)一般用来处理数据(读取/设置),一般指操作数据库。
视图(View)一般用来展示数据,比如通过HTML展示。
控制器(Controller)一般用做连接模型和视图的桥梁。

通过ThinkPHP来演示后端MVC的执行流程,其重点在于理解。
MVC更多应用在后端开发程序里,后被引入到前端开发中,由于受到前端技术的限制便有了一些细节的调整,进而出现了很多MVC的衍生版(子集)如MVVM、MVW、MVP、MV*等。
注:做为初学可以不必过于在意这些概念。

1.在开发网站中,所有的功能其实都是前端人员发送请求并接受相应,然后将响应的数据放到页面中去。
数据---->页面(对应数据要展示的对应页面),将处理数据的角色,称为模型(Model)。展示数据的角色称为视图(View)。为了保证对应的数据要展示到对应的页面上,需要分配,称为控制器(controller)。
[MVC是一种开发的模式,采用这种开发模式可以使开发变得更加高效。]
2.通过米快画的形式开发,每个模块下包括MVC,使用HTML在构建是变得灵活。
2.1当引入angular.js后会提供一个全局对象angular,在此对象下有若干的方法,其次module方法可以创建模块 var App=angluar.module("App",[]);
2.2每个模块包括MVC,模块实例也是一个对象,在此对象下有若干的方法,其次controller方法创建一个控制器,App.controller('Demo',['$scope',function($scope){}]);$scopr即模型(Model)
2.3视图即HTML,每一个视图都隶属于某一个控制器,通过ng-controller进行指定,ng-controller="Demo"
第2章模块化
使用AngularJS构建应用(App)时是以模块化(Module)的方式组织的,即将整个应用划分成若干模块,每个模块都有各自的职责,最终组合成一个整体。
采用模块化的组织方式,可以最大程度的实现代码的复用,可以像搭积木一样进行开发。

2.1 定义应用
通过为任一HTML标签添加ng-app属性,可以指定一个应用,表示此标签所包裹的内容都属于应用(App)的一部分。

2.2 定义模块
AngularJS提供了一个全局对象angular,在此全局对象下存在若干的方法,其中angular.module()方法用来定义一个模块。

注:应用(App)其本质也是一个模块(一个比较大的模块)。
2.3 定义控制器
控制器(Controller)作为连接模型(Model)和视图(View)的桥梁存在,所以当我们定义好了控制器以后也就定义好了模型和视图。

模型(Model)数据是要展示到视图(View)上的,所以需要将控制器(Controller)关联到视图(View)上,通过为HTML标签添加ng-controller属性并赋值相应的控制器(Controller)的名称,就确立了关联关系。

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>AnguarJS 模块</title><script src="./libs/angular.min.js"></script><script>// 提供一个全局对象 angular// 在这个对象下有若干方法,可以实现具体功能// 其中module方法可以创建一个模块// 需要两个参数,第1个为模块名称,第2个为依赖(目前空数组)var App = angular.module('App', []);// 要完成功能还需要MVC// 上一步创建的模块其返回值App也是一个对象// 在此对象下又有若干方法,其中controller方法// 可以创建一个控制器App.controller('Demo', ['$scope', function ($scope) {// $scope 是一个空对象{}// 就是Model$scope.name = '你好 itcast';$scope.courses = ['html', 'css', 'js'];$scope.stars = [{name: '刘德华', age: 60, sex: '男', area: '香港'},{name: '王力宏', age: 39, sex: '男', area: '台湾'},{name: '周杰伦', age: 37, sex: '男', area: '台湾'}];}]);// for(var i=0; i<courses.length; i++) {// courses[i]// }</script></head><body ng-app="App"><div class="box" ng-controller="Demo"><h1>{{name}}</h1><ul><li ng-repeat="i in courses">{{i}}</li></ul><table><tr><td>姓名</td><td>性别</td><td>年龄</td><td>地区</td></tr><tr ng-repeat="star in stars"><td>{{star.name}}</td><td>{{star.sex}}</td><td>{{star.age}}</td><td>{{star.area}}</td></tr></table></div></body></html>
以上步骤就是AngularJS最基本的MVC工作模式。
下图是AngularJS的结构,学习AngularJS会围绕下图的结构展开。

第3章指令
HTML在构建应用(App)时存在诸多不足之处,AngularJS通过扩展一系列的HTML属性或标签来弥补这些缺陷,所谓指令就是AngularJS自定义的HTML属性或标签,这些指令都是以ng-做为前缀的,例如ng-app、ng-controller、ng-repeat等。
3.1 内置指令
ng-app 指定应用根元素,至少有一个元素指定了此属性。
ng-controller 指定控制器
ng-show控制元素是否显示,true显示、false不显示
ng-hide控制元素是否隐藏,true隐藏、false不隐藏
ng-if控制元素是否“存在”,true存在、false不存在
ng-src增强图片路径
ng-href增强地址
ng-class控制类名
ng-include引入模板
ng-disabled表单禁用
ng-readonly表单只读
ng-checked单/复选框表单选中
ng-selected下拉框表单选中
<!DOCTYPE html><html lang="en" ng-app="App"><head><meta charset="UTF-8"><title>Document</title><style>.red {color: red;}.blue {color: blue;}</style><script src="./libs/angular.min.js"></script></head><body><!-- <img src="./images/author.jpg" alt=""> --><div ng-controller="DemoController"><link rel="stylesheet" ng-href="{{link}}"><p ng-show="false">学习使用ng-show指令,当属性值true时显示,否则隐藏</p><p ng-hide="0">学习使用ng-hide指令,当属性值true时隐藏,否则显示</p><p ng-if="1">学习使用ng-if指令,当属性值true时显示,否则隐藏</p><img ng-src="{{path}}" alt=""><p class="{{color}}">一些文字</p><p ng-class="{red: false, blue: true}">另一些文字</p><form action=""><ul><li>姓名:<input type="text" value="itcast" ng-disabled="false"></li><li>地区:<input type="text" value="河北省" ng-readonly="true"></li><li>爱好: 写代码<input type="checkbox" ng-checked="false"></li><li>科目:<select name="" id=""><option value="0">PHP</option><option value="0" ng-selected="false">前端</option><option value="0">UI</option></select></li></ul></form></div><script>// ng-app 指定一个应用// 可以用应用任意标签上,并且将此标签包括区// 视为一个应用的范围// 一个页面可以有多个但是不能进行嵌套,一般指定一个var App = angular.module('App', []);// ng-controller 指定某视图隶属于某一个控制器App.controller('DemoController', ['$scope', function ($scope) {$scope.path = './images/author.jpg';$scope.link = './css/base.css';$scope.color = 'red';}]);</script></body></html>
注:后续学习过程中还会介绍其它指令。
3.2 自定义指令
AngularJS允许根据实际业务需要自定义指令,通过angular全局对象下的directive方法实现。

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>AngularJS 自定义指令</title><script src="./libs/angular.min.js"></script><script>var App = angular.module('Demo', []);// 自定义控制器App.controller('ItcastController', ['$scope', function ($scope) {$scope.list = ['html', 'css', 'js'];}]);// 自定义指令// 第一个参数,指令的名称// 第二个参数,回调函数App.directive('itcast', function () {// 此回调函数指定具体指令应该做哪些事情// 通过一个对象来定义var obj = {// 自定义指令可以是属性可以是标签// E element// A attribute// C class// M markrestrict: 'ECMA',// 所有内容必须包含在一个根元素下template: '<div><h1>你好, AngularJS!</h1><p>哈哈</p></div>',// templateUrl: './header.html',replace: true,// scope: {},// link: function () {},// compile: function () {}}return obj;});</script></head><body ng-app="Demo"><div itcast></div><itcast></itcast><div class="itcast"></div><!-- directive:itcast --><ul ng-controller="ItcastController"><li ng-repeat="item in list">{{item}}</li></ul></body></html>
第4章数据绑定
AngularJS是以数据做为驱动的MVC框架,所有模型(Model)里的数据经由控制器(Controller)展示到视图(View)中。
所谓数据绑定指的就是将模型(Model)中的数据与相应的视图(View)进行关联,分为单向绑定和双向绑定两种方式。
4.1 单向绑定
单向数据绑定是指将模型(Model)数据,按着写好的视图(View)模板生成HTML标签,然后追加到DOM中显示,如之前所学的artTemplate 模板引擎的工作方式。
如下图所示,只能模型(Model)数据向视图(View)传递。

4.2 双向绑定
双向绑定则可以实现模型(Model)数据和视图(View)模板的双向传递,如下图所示。

4.3 相关指令
在AngularJS中通过“{{}}”和ng-bind指令来实现模型(Model)数据向视图模板(View)的绑定,模型数据通过一个内置服务$scope来提供,这个$scope是一个空对象,通过为这个对象添加属性或者方法便可以在相应的视图(View)模板里被访问。
注:“{{}}”是ng-bind的简写形式,其区别在于通过“{{}}”绑定数据时会有“闪烁”现象,添加ng-cloak也可以解决“闪烁”现象,通过ng-bind-template可以绑定多个数据。
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>AngularJS 数据绑定</title><script src="./libs/angular.min.js"></script></head><body ng-app="Demo"><div class="box" ng-controller="DemoController"><!-- <h1 ng-cloak>{{name}}<small ng-bind="age"></small></h1> --><!-- <h1>{{name}}{{age}}</h1> --><h1 ng-bind-template="{{name}}{{age}}"></h1><ul><li ng-repeat="course in courses">{{course}}</li></ul></div><script>var App = angular.module('Demo', []);App.controller('DemoController', ['$scope', function ($scope) {$scope.name = '小明';$scope.age = '18';$scope.courses = ['html', 'css', 'js'];}]);</script></body></html>
通过为表单元素添加ng-model指令实现视图(View)模板向模型(Model)数据的绑定。
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>AngularJS 数据绑定</title><script src="./libs/angular.min.js"></script><script>var App = angular.module('App', []);App.controller('DemoController', ['$scope', function ($scope) {$scope.msg = '你好!!!!!';$scope.testmsg = '';$scope.show = function () {// 可以输出模型数据alert($scope.msg);// alert($scope.testmsg);}}]);</script></head><body ng-app="App"><div ng-controller="DemoController"><h3>{{msg}}</h3><input type="text" ng-model="testmsg"><h4>{{testmsg}}</h4><button ng-click="show()">显示</button></div></body></html>
通过ng-init可以初始化模型(Model)也就是$scope。
<!DOCTYPE html><html lang="en" ng-app="App"><head><meta charset="UTF-8"><title>AngularJS 数据绑定</title></head><body><div ng-controller="DemoController" ng-init="name='小明'; age=18"><h1>{{name}}</h1><small>{{age}}</small></div><script src="./libs/angular.min.js"></script><script>var App = angular.module('App', []);App.controller('DemoController', ['$scope', function ($scope) {// $scope.name = "小明";}]);</script></body></html>
AngularJS对事件也进行了扩展,无需显式的获取DOM元素便可以添加事件,易用性变的更强。通过在原有事件名称基础上添加ng-做为前缀,然后以属性的形式添加到相应的HTML标签上即可。如ng-click、ng-dblclick、ng-blur等。
<!DOCTYPE html><html lang="en" ng-app="App"><head><meta charset="UTF-8"><title>AngularJS 数据绑定</title><style>ul {list-style: none;}.mouseover {width: 100px;height: 100px;background-color: pink;}</style></head><body><div ng-controller="DemoController"><ul><li>{{name}}</li><li><button ng-click="myclick()">点击</button></li><li class="mouseover" ng-mouseout="mymouseout()" ng-mouseover="mymouseover()"></li><li><input type="text" ng-keydown="mykeydown()"></li></ul></div><script src="./libs/angular.min.js"></script><script>var App = angular.module('App', []);App.controller('DemoController', ['$scope', function ($scope) {$scope.name = '小明';$scope.myclick = function () {alert('点击了一下?');}$scope.mymouseover = function () {console.log('鼠标经过过?');}$scope.mymouseout = function () {console.log('鼠标离开了?');}$scope.mykeydown = function () {console.log('按键被按下');}}]);</script></body></html>
通过ng-repeat可以将数组或对象数据迭代到视图模板中,ng-switch、on、ng-switch-when可以对数据进行筛选。
<!DOCTYPE html><html lang="en" ng-app="App"><head><meta charset="UTF-8"><title>AngularJS 数据绑定</title></head><body><div ng-controller="DemoController"><ul><li ng-repeat="val in obj">{{val}}</li></ul><ul><li ng-repeat="val in courses" ng-switch on="val"><span ng-switch-when="css">{{val}}</span></li></ul></div><script src="./libs/angular.min.js"></script><script>var App = angular.module('App', []);App.controller('DemoController', ['$scope', function ($scope) {$scope.obj = {name: '小明',age: 18}$scope.courses = ['html', 'css', 'js'];}]);var arr = ['html', 'css', 'js'];for(var i=0; i<arr.length; i++) {if(arr[i] == 'css') {console.log(arr[i])}}// switch($str) {// case 'css':// console.log($str);// break;// case 'js'// }</script></body></html>

第5章作用域
通常AngularJS中应用(App)是由若干个视图(View)组合成而成的,而视图(View)又都是HTML元素,并且HTML元素是可以互相嵌套的,另一方面视图都隶属于某个控制器(Controller),进而控制器之间也必然会产生嵌套关系。
每个控制器(Controller)又都对应一个模型(Model)也就是$scope对象,不同层级控制器(Controller)下的$scope便产生了作用域。
5.1 根作用域
一个AngularJS的应用(App)在启动时会自动创建一个根作用域$rootScope,这个根作用域在整个应用范围(ng-app所在标签以内)都是可以被访问到的。

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Document</title><script src="./libs/angular.min.js"></script><script>var App = angular.module('App', []);//App.controller('ParentController', ['$scope', function ($scope) {// $scope.name = '康熙';}]);App.controller('ChildController', ['$scope', function ($scope) {// $scope.name = '雍正';}]);var a = 10;function fn() {// a = 15;alert(a);function bar() {// a = 20;alert(a);}bar();}fn();</script></head><body><div class="box" ng-app="App" ng-init="name='顺治'"><div class="parent" ng-controller="ParentController"><dl><dt>{{name}}</dt><dd></dd></dl><div class="child" ng-controller="ChildController"><dl><dt>---{{name}}</dt><dd></dd></dl></div></div></div></body></html>
5.2 子作用域
通过ng-controller指令可以创建一个子作用域,新建的作用域可以访问其父作用域的数据。
第6章过滤器
在AngularJS中使用过滤器格式化展示数据,在“{{}}”中使用“|”来调用过滤器,使用“:”传递参数。
6.1 内置过滤器
1、currency将数值格式化为货币格式
2、date日期格式化,年(y)、月(M)、日(d)、星期(EEEE/EEE)、时(H/h)、分(m)、秒(s)、毫秒(.sss),也可以组合到一起使用。
3、filter在给定数组中选择满足条件的一个子集,并返回一个新数组,其条件可以是一个字符串、对象、函数
4、json将Javascrip对象转成JSON字符串。
5、limitTo取出字符串或数组的前(正数)几位或后(负数)几位
6、lowercase将文本转换成小写格式
7、uppercase将文本转换成大写格式
8、number数字格式化,可控制小位位数
9、orderBy对数组进行排序,第2个参数可控制方向
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>AngularJS 过滤器</title></head><body ng-app="App"><ul ng-controller="DemoController"><li>当前时间为: {{now|date:'y-M-d hh:mm:ss'}}</li><li>商品价格: {{price|currency:'¥':4}}</li><li>你叫啥: {{desc|uppercase}}</li><li>年龄: {{age|lowercase}}</li><li>数值: {{num|number:3}}</li><li>转JSON: {{obj|json}}</li><li>截取: {{desc|limitTo:-4}}</li><li>截取: {{items|limitTo:2:3}}</li><li>排序: {{students|orderBy:'score':false}}</li><li>过滤: {{students|filter:'小明'}}</li><li>过滤: {{students|filter:{name:'小牛'} }}</li><li>过滤: {{courses|filter: 'p'}}</li></ul><script src="./libs/angular.min.js"></script><script>var App = angular.module('App', []);App.controller('DemoController', ['$scope', function ($scope) {$scope.now = new Date;$scope.price = 12.345;$scope.desc = 'my name is xiaoming';$scope.age = 'HOw Old are you?';$scope.num = 123.4567;$scope.obj = {name: '小明', age: 18};$scope.items = ['html', 'css', 'js', 'php', 'java'];$scope.students = [{name: '小明', age: 18, score: 99},{name: '小红', age: 16, score: 96},{name: '小牛', age: 19, score: 97}];$scope.courses = ['php', 'java', 'javascript', 'photoshop'];}])</script></body></html>
6.2 自定义过滤器
除了使用AngularJS内建过滤器外,还可以根业务需要自定义过滤器,通过模块对象实例提供的filter方法自定义过滤器。
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>AngularJS 自定义过滤器</title><script src="./libs/angular.min.js"></script><script>var App = angular.module('App', []);// 定义控制器App.controller('DemoController', ['$scope', function ($scope) {$scope.str = '测试内容';$scope.price = 12.345;$scope.desc = 'my name is laozhao';}]);// 定义指令// App.directive();// 定义过滤器// 过滤器本质就一个函数// 第1个参数为过滤器名称(函数名称)// 第2个参数为回调函数App.filter('demo', function () {// 在此定义过滤器具体的功能// function abc() {// console.log('1111');// }// return abc;return function (arg, type, fixed) {// return arg + arg2 + arg3;return type + arg.toFixed(fixed);}});// 自定义一个实英文首字母大定的过滤器App.filter('capitalize', function () {return function (input) {console.log(input);return input[0].toUpperCase() + input.slice(1);}});</script></head><body ng-app="App"><div ng-controller="DemoController"><dl><dt>自定义过滤器</dt><dd>{{price|demo:'¥':2}}</dd><dd>{{desc|capitalize}}</dd></dl></div></body></html>
第7章依赖注入
AngularJS采用模块化的方式组织代码,将一些通用逻辑封装成一个对象或函数,实现最大程度的复用,这导致了使用者和被使用者之间存在依赖关系。 
所谓依赖注入是指在运行时自动查找依赖关系,然后将查找到依赖传递给使用者的一种机制。
常见的AngularJS内置服务有$http、$location、$timeout、$rootScope等
7.1 推断式注入
没有明确声明依赖,AngularJS会将函数参数名称当成是依赖的名称。

这种方式会带来一个问题,当代码经过压缩后函数的参数被压缩,这样便会造成依赖无法找到。
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>AngularJS 依赖注入</title></head><body ng-app="App"><div class="box" ng-controller="DemoController"><h1>{{name}}</h1></div><script src="./libs/angular.min.js"></script><script>var App = angular.module('App', []);// AngularJS 内置一些具有特殊功能的“模块”// 开发者在开发的时候可以直接使用这些“模块”App.controller('DemoController', function ($scope, $http) {$scope.name = '推断式';});</script></body></html>
7.2 行内注入
以数组形式明确声明依赖,数组元素都是包含依赖名称的字符串,数组最后一个元素是依赖注入的目标函数。

推荐使用这种方式声明依赖
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>AngularJS 依赖注入</title><script src="./libs/angular.min.js"></script><script>var App = angular.module('App', []);// 写一个控制器// $scope 就是AngularJS 事件提供供的一个功能模块// 数组是用来声明需要依赖哪些功能模块的// 数组最后一个单元必须为函数,函数的参数即注入// angularJS将查找得到的功能模块以参数的形式传入// 最后一个数组单元传递的函数,这个过程称为注入// 行内式依赖注入App.controller('DemoController', ['$scope', '$http', '$rootScope', function ($scope, $http, $rootScope) {$scope.name = '依赖注入';}]);// 依赖注入并非只能用于定义控制器时,// 只是我们目前接触控制器最多,拿它举例说明</script></head><body ng-app="App"><div ng-controller="DemoController"><h1>{{name}}</h1></div></body></html>
第8章服务
服务是一个对象或函数,对外提供特定的功能。
8.1 内建服务
1、$location是对原生Javascript中location对象属性和方法的封装。
        $location是关于链接的操作,hash是特殊的,#号后面的都封装成hash了,方便调用别的方法。

<!DOCTYPE html><html lang="en" ng-app="App"><head><meta charset="UTF-8"><title>AngularJS 服务</title></head><body><dl ng-controller="DemoController"><dt>$location服务</dt><a href="#/abc?name=itcast&age=10#hash">地址</a><dd>absUrl: {{absUrl}}</dd><dd>host: {{host}}</dd><dd>port: {{port}}</dd><dd>hash: {{hash}}</dd><dd>search: {{search}}</dd><dd>protocol: {{protocol}}</dd></dl><script src="./libs/angular.min.js"></script><script>var App = angular.module('App', []);// $location内置服务// AngularJS 专门提供了一个帮助获取URL地址一个服务App.controller('DemoController', ['$scope', '$location', function ($scope, $location) {console.log($location);// 获取绝对路径$scope.absUrl = $location.absUrl();$scope.host = $location.host();$scope.port = $location.port();// angularjs 对hash做了特别的处理$scope.hash = $location.hash();$scope.search = $location.search();$scope.protocol = $location.protocol();}]);// 一个完整地址是包括若干部分的// http://www.baidu.com:80// http://localhost/02day/4-code/$http.html// http://localhost/02day/4-code/$http.html?name=小明&age=10// http://localhost/02day/4-code/$http.html#demo// http 表示协议// localhost/127.0.0.1/www.baidu.com 表示主机// 80 表示端口号// # 表示锚链接// ? 表示查询参数或叫queryString// 02day/4-code 表示pathname// js BOM 提供了一个对象 location 可以获取地址的任一部分for(var key in location) {console.log(key + '~~~' + location[key]);}</script></body></html>
2、$timeout&$interval对原生Javascript中的setTimeout和setInterval进行了封装。
$timeout是等待多久后执行,$interval是间歇执行。
清除定时器:$interval.cancel(interval赋值的变量)。

<!DOCTYPE html><html lang="en" ng-app="App"><head><meta charset="UTF-8"><title>AngularJS 服务</title></head><body><div ng-controller="DemoController"><ul><li>{{msg}}</li><li>{{count}}</li><li>{{now|date:'yyyy-MM-dd hh:mm:ss'}}</li><li><button ng-click="start()">开始计时</button></li><li><button ng-click="stop()">停止计时</button></li></ul></div><script src="./libs/angular.min.js"></script><script>var App = angular.module('App', []);// $timeout 和 $intervalApp.controller('DemoController', ['$scope', '$timeout', '$interval',function ($scope, $timeout, $interval) {// $timeout(function () {// $scope.msg = '我在1秒后显示';// }, 1000);// var count = 0;// $interval(function () {// $scope.count = count++;// }, 500);var timer;$scope.start = function () {timer = $interval(function () {$scope.now = new Date;}, 1000);}$scope.stop = function () {// 清$interval.cancel(timer);}}])</script></body></html>
3、$filter过滤器在控制器中格式化数据,用来处理数据格式的。

<!DOCTYPE html><html lang="en" ng-app="App"><head><meta charset="UTF-8"><title>AngularJS 服务</title></head><body><ul ng-controller="DemoController"><li>价格: {{price}}</li><li>大写: {{intro}}</li><li>截取: {{list}}</li></ul><script src="./libs/angular.min.js"></script><script>var App = angular.module('App', []);// 前面学习过滤器,主要应用在{{}}中// 但是也会有需求,在控制器中使用,这时需要用到一个// 叫$filter的服务// $filter是过滤器App.controller('DemoController', ['$scope', '$filter', function ($scope, $filter) {// $filter服务仍然是处理数据格式的var price = 12.345; // ¥12.345;var currency = $filter('currency');$scope.price = currency(price, '¥', 3);var intro = 'my name is laozhao';var uppercase = $filter('uppercase');$scope.intro = uppercase(intro);var list = ['html', 'css', 'js'];var limitTo = $filter('limitTo');$scope.list = limitTo(list, 2);}])</script></body></html>
4、$log打印调试信息

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>AngularJS 服务</title><script src="./libs/angular.min.js"></script><script>var App = angular.module('App', []);// $scope是一个具有特定功能的模块// 在AngularJS中将具有特定功能的模块称为服务App.controller('DemoController', ['$scope', '$log', function ($scope, $log) {// $scope 是一个AngularJS内置服务,可以充当模型这个角色$scope.name = '小明';// $log是一个内置的服务,可以帮助开发者在开发阶段进行调试$log.debug('调试信息');$log.info('信息');$log.log('打印');$log.error('错误');$log.warn('警告');}]);</script></head><body ng-app="App"><div ng-controller="DemoController"><h1>{{name}}</h1></div></body></html>
5、$http用于向服务端发起异步请求。

同时还支持多种快捷方式如$http.get()、$http.post()、$http.jsonp。
注:各参数含义见代码注释。
GET:
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>AngularJS $http服务</title></head><body ng-app="App"><div ng-controller="DemoController"><h1>练习$http</h1></div><script src="./libs/angular.min.js"></script><script>var App = angular.module('App', []);App.controller('DemoController', ['$http', '$log', function ($http, $log) {// $http 是angularJS内置服务,可以向服务器发起异步请求$http({url: './example.php', // 请求地址method: 'get', // 请求方式params: {sex: '男'}, // 专门用来传递get形式的参数// AngularJS 以get形式传参时,并没有使用datadata: 'name=小明&age=10' // 专门用来传post形式的参数}).success(function (info) { // 响应成功后会执行// info 即服务端返回的数据$log.info(info);});}]);// XMLHttpRequest// var xhr = new XMLHttpRequest;// xhr.open('post', './example.php');// xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');// 之所以在jQuery可以通data以对象形式传递参数// 是因jQuery内部进行处理(key=val&key1=val1)// 之所以在jQuery中传递参数不论get或post都可以使用// data传递,是因为在jQuery内部做了判断将参数放到不同位置了// 标准格式 key=val&key1=val1// xhr.send('name=小明&age=10');// $.ajax({// url: './example.php',// type: 'post',// data: {name: 'itcast', age: 10}// })</script></body></html>
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>AngularJS $http服务</title></head><body ng-app="App"><div ng-controller="DemoController"><h1>练习$http</h1></div><script src="./libs/angular.min.js"></script><script>var App = angular.module('App', []);App.controller('DemoController', ['$http', '$log', function ($http, $log) {// $http 是angularJS内置服务,可以向服务器发起异步请求$http({url: './example.php', // 请求地址method: 'post', // 请求方式// angularJS没有将一个对象数据转换成// key=val&key1=val1// data: {name: '小明', age: 18}, // 传递参数data: 'name=小明&age=10',headers: {'Content-Type': 'application/x-www-form-urlencoded'}}).success(function (info) { // 响应成功后会执行// info 即服务端返回的数据$log.info(info);});}]);// XMLHttpRequest// var xhr = new XMLHttpRequest;// xhr.open('post', './example.php');// xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');// 之所以在jQuery可以通data以对象形式传递参数// 是因jQuery内部进行处理(key=val&key1=val1)// 标准格式 key=val&key1=val1// xhr.send('name=小明&age=10');// $.ajax({// url: './example.php',// type: 'post',// data: {name: 'itcast', age: 10}// })</script></body></html>
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>AngularJS $http服务</title></head><body ng-app="App"><div ng-controller="DemoController"><h1>练习$http</h1></div><script src="./libs/angular.min.js"></script><script>var App = angular.module('App', []);App.controller('DemoController', ['$http', '$log', function ($http, $log) {$http({url: './jsonp.php',method: 'jsonp', // 使用JSONP请求// JSON原理中需要将前端“事先”定义好的一个函数名// 传递给后端,后在返回这个函数调用(函数名())// 并且在调用时传递一个实参,通过这种方式可以间接// 获取服务端数据// 类似这种格式值angular.callbacks._0被添加到了// 请求后面,angular.callbacks._0就是angularjs事先定义好的一个函数名字// angular.callbacks._0();params: {callback: 'JSON_CALLBACK'}}).success(function (info) {$log.info(info);});// $.ajax({// url: '',// dataType: 'jsonp',// success: function (info) {// }// });}]);</script></body></html>
8.2 自定义服务
通过上面例子得知,所谓服务是将一些通用性的功能逻辑进行封装方便使用,AngularJS允许将自定义服务。

1、factory方法

<!DOCTYPE html><html lang="en" ng-app="App"><head><meta charset="UTF-8"><title>AngularJS 自定义服务</title></head><body><div ng-controller="DemoController"><span>{{now}}</span><button ng-click="show()">显示时间</button></div><script src="./libs/angular.min.js"></script><script>var App = angular.module('App', []);// App.directive(); 自定义指令// App.filter(); 自定义过滤器// App.controller(); “自定义”控制器// App.factory(); 自定义服务// 定义一个名叫showTime的服务App.factory('showTime', ['$filter', function ($filter) {function show() {// 当外部调用show方法时// 将结果返回return $filter('date')(new Date, 'yyyy-MM-dd hh:mm:ss');}// 将封装好的服务返回,供外部使用// 可以以对象形式也可以直接返回函数// return show// 或者return {show: show}}]);// 定义一个控制器,将自定义的服务注入进来// 测试App.controller('DemoController', ['$scope', 'showTime', function ($scope, showTime) {// showTime就是自定义的服务$scope.show = function () {// 当我们自定义的服务返回一个对象时// 使用 showTime.show()// $scope.now = showTime.show();// 当我们自定义的服务直接返回函数时// 使用showTime();$scope.now = showTime();};}]);</script></body></html>
2、service方法

<!DOCTYPE html><html lang="en" ng-app="App"><head><meta charset="UTF-8"><title>AngularJS 自定义服务</title></head><body><div ng-controller="DemoController"><h1>{{now}}</h1></div><script src="./libs/angular.min.js"></script><script>var App = angular.module('App', []);// 自定义服务// 通过 servie定义一个服务// 第1个参数是自定义服务名称// 第2个参数是依赖注入App.service('showTime', ['$filter', function ($filter) {// 将定义好的服务添加到this对象上// 外部就可以使用了// $filter可以直接拿来用this.show = function (format) {return $filter('date')(new Date, format);}}]);// 自定义一个控制器,测试自定义服务App.controller('DemoController', ['$scope', 'showTime', function ($scope, showTime) {$scope.now = showTime.show('MM');}])</script></body></html>
3、value方法定义常量

<!DOCTYPE html><html lang="en" ng-app="App"><head><meta charset="UTF-8"><title>AngularJS 自定义服务</title></head><body><div ng-controller="DemoController">{{author}}{{version}}</div><script src="./libs/angular.min.js"></script><script>var App = angular.module('App', []);// 自定义常量服务App.value('author', 'itcast');App.value('version', '1.0');// 本质上一个服务// 从表现形式上是一个常量// 常量就是不变的值与变对量相对应// 声明依赖调用服务App.controller('DemoController', ['$scope', 'author', 'version', function ($scope, author, version) {$scope.author = author;$scope.version = version;}])</script></body></html>
在介绍服务时曾提到服务本质就是一个对象或函数,所以自定义服务就是要返回一个对象或函数以供使用。
第9章模块加载
AngularJS模块可以在被加载或者执行之前对其自身进行配置。我们可以在应用的加载阶段配置不同的逻辑。

9.1 配置块
1、通过config方法实现对模块的配置,AngularJS中的服务大部分都对应一个“provider”,用来执行与对应服务相同的功能或对其进行配置。
比如$log、$http、$location都是内置服务,相对应的“provider”分别是$logProvider、$httpProvider、$locationPorvider。
下图以$log为例进行演示,修改了配置

下图以$filter为例进行演示,实现相同功能

<!DOCTYPE html><html lang="en" ng-app="App"><head><meta charset="UTF-8"><title>AngularJS 服务</title></head><body><ul ng-controller="DemoController"><li>价格: {{price}}</li><li>大写: {{intro}}</li><li>截取: {{list}}</li></ul><script src="./libs/angular.min.js"></script><script>var App = angular.module('App', []);// 前面学习过滤器,主要应用在{{}}中// 但是也会有需求,在控制器中使用,这时需要用到一个// 叫$filter的服务// $filter是过滤器App.controller('DemoController', ['$scope', '$filter', function ($scope, $filter) {// $filter服务仍然是处理数据格式的var price = 12.345; // ¥12.345;var currency = $filter('currency');$scope.price = currency(price, '¥', 3);var intro = 'my name is laozhao';var uppercase = $filter('uppercase');$scope.intro = uppercase(intro);var list = ['html', 'css', 'js'];var limitTo = $filter('limitTo');$scope.list = limitTo(list, 2);}])</script></body></html>
9.2 运行块
服务也是模块形式存在的对且对外提供特定功能,前面学习中都是将服务做为依赖注入进去的,然后再进行调用,除了这种方式外我们也可以直接运行相应的服务模块,AngularJS提供了run方法来实现。
rootScope根作用域(相当于window)

不但如此,run方法还是最先执行的,利用这个特点我们可以将一些需要优先执行的功能通过run方法来运行,比如验证用户是否登录,未登录则不允许进行任何其它操作。
<!DOCTYPE html><html lang="en" ng-app="App" ng-init="name='顺治'"><head><meta charset="UTF-8"><title>AngularJS 模块加载</title></head><body><div ng-controller="DemoController">{{name}}{{age}}</div><script src="./libs/angular.min.js"></script><script>var App = angular.module('App', []);// 在AngularJS中某些模块是可以直接运行的// 使用 App.run()// 例如直接运行$http、$rootScope服务// $rootScope根作域(相当于window)App.run(['$http', '$rootScope', function ($http, $rootScope) {// 定义全局作用域$rootScope.name = '顺治';$rootScope.age = '28';// 利用$http发送异步请求$http({url: './example.php'}).success(function (info) {console.log(info);});}]);// 定义制器测试全局作用域App.controller('DemoController', ['$scope', function ($scope) {// $scope.name = '康熙';}])</script></body></html>
注:此知识点意在了解AngularJS的加载机制。
第10章路由
一个应用是由若个视图组合而成的,根据不同的业务逻辑展示给用户不同的视图,路由则是实现这一功能的关键。
10.1 SPA
SPA(Single Page Application)指的是通单一页面展示所有功能,通过Ajax动态获取数据然后进行实时渲染,结合CSS3动画模仿原生App交互,然后再进行打包(使用工具把Web应用包一个壳,这个壳本质上是浏览器)变成一个“原生”应用。
在PC端也有广泛的应用,通常情况下使用Ajax异步请求数据,然后实现内容局部刷新,局部刷新的本质是动态生成DOM,新生成的DOM元素并没有真实存在于文档中,所以当再次刷新页面时新添加的DOM元素会“丢失”,通过单页面应可以很好的解决这个问题。
10.2 路由(约等于地址)前端路由就是封装了锚链接
在后端开发中通过URL地址可以实现页面(视图)的切换,但是AngularJS是一个纯前端MVC框架,在开发单页面应用时,所有功能都在同一页面完成,所以无需切换URL地址(即不允许产生跳转),但Web应用中又经常通过链接(a标签)来更新页面(视图),当点击链接时还要阻止其向服务器发起请求,通过锚点(页内跳转)可以实现这一点。
实现单页面应用需要具备:
a、只有一页面
b、链接使用锚点
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>AngularJS 路由和多视图</title><style>body {padding: 0;margin: 0;background-color: #F7F7F7;font-family: Arial;}.wrapper {width: 980px;margin: 50px auto;}ul {padding: 0;margin: 0;overflow: hidden;list-style: none;background-color: #000;border-radius: 4px;}li {float: left;width: 120px;height: 40px;text-align: center;line-height: 40px;font-size: 18px;}li.active {background-color: #333;}li a {display: block;color: #FFF;text-decoration: none;}.content {margin-top: 30px;font-size: 24px;padding: 0 20px;}</style></head><body ng-app="App"><div class="wrapper"><!-- 导航菜单 --><ul><li class="active"><a href="#/index">Index</a></li><li><a href="#/introduce">Introduce</a></li><li><a href="#/contact">Contact Us</a></li></ul><!-- 内容 --><div class="content"><!-- 占位符 --><div ng-view></div></div></div><!-- 引入核心框架 --><script src="./libs/angular.min.js"></script><!-- 引入路由模块 --><script src="./libs/angular-route.js"></script><script>var App = angular.module('App', ['ngRoute']);// 就可以使用路由模块了// 路由模块需要经过一系列配置才可以使用// $routeProviderApp.config(['$routeProvider', function ($routeProvider) {// 第1个参数路由的变化// 第2个参数当前路由的具体逻辑$routeProvider.when('/index', {template: '<h1>Index Page!</h1>'}).when('/introduce', {template: '<h1>Introduce Page!</h1>'}).when('/contact', {template: '<h1>Contact Us Page!</h1>'}).when('/404', {template: '<h1 style="color:red;">Not Found</h1>'}).otherwise({redirectTo: '/404'});}]);</script></body></html>
通过上面的例子发现在单一页面中可以能过hashchange事件监听到锚点的变化,进而可以实现为不同的锚点准不同的视图,单页面应用就是基于这一原理实现的。
AngularJS对这一实现原理进行了封装,将锚点的变化封装成路由(Route),这是与后端路由的根本区别。
在1.2版前路由功能是包含在AngularJS核心代码当中,之后的版本将路由功能独立成一个模块,下载angular-route.js
要实现更新数据,需要发送请求找服务器要,当锚点发送改变后再要数据,使用hashchange事件,添加给window对象,这个事件会在锚点发生改变的时候触发
window.addEventListener('hashchangge',function(){
    
});
10.2.1 使用
1、引入angular-route.js

2、实例化模块(App)时,当成依赖传进去(模块名称叫ngRoute)。

3、配置路由模块

4、布局模板
通过ng-view指令布局模板,路由匹配的视图会被加载渲染到些区域。

10.2.1 路由参数
1、提供两个方法匹配路由,分别是when和otherwise,when方法需要两个参数,otherwise方法做为when方法的补充只需要一个参数,其中when方法可以被多次调用。
2、第1个参数是一个字符串,代表当前URL中的hash值。
3、第2个参数是一个对象,配置当前路由的参数,如视图、控制器等。
	a、template 字符串形式的视图模板
	b、templateUrl 引入外部视图模板
	c、controller 视图模板所属的控制器
	d、redirectTo跳转到其它路由
4、获取参数,在控制中注入$routeParams可以获取传递的参数


<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>AngularJS 路由和多视图</title><style>body {padding: 0;margin: 0;background-color: #F7F7F7;font-family: Arial;}.wrapper {width: 980px;margin: 50px auto;}ul {padding: 0;margin: 0;overflow: hidden;list-style: none;background-color: #000;border-radius: 4px;}li {float: left;width: 120px;height: 40px;text-align: center;line-height: 40px;font-size: 18px;}li.active {background-color: #333;}li a {display: block;color: #FFF;text-decoration: none;}.content {margin-top: 30px;font-size: 24px;padding: 0 20px;}</style></head><body ng-app="App"><div class="wrapper"><!-- 导航菜单 --><ul><li class="active"><a href="#/index">Index</a></li><li><a href="#/introduce">Introduce</a></li><li><a href="#/contact">Contact Us</a></li></ul><!-- 内容 --><div class="content"><!-- 占位符 --><div ng-view></div></div></div><!-- 引入核心框架 --><script src="./libs/angular.min.js"></script><!-- 引入路由模块 --><script src="./libs/angular-route.js"></script><script>var App = angular.module('App', ['ngRoute']);App.config(['$routeProvider', function ($routeProvider) {$routeProvider.when('/index', {// 引入外部视图模板templateUrl: './views/index.tpl',// 为引入的视图模板指定控制器controller: 'IndexController'}).when('/introduce', {templateUrl: './views/introduce.html'}).when('/contact', {templateUrl: './views/concat.tpl'})}])// 定义控制器App.controller('IndexController', ['$scope', '$http', function ($scope, $http) {// $http({// url: ''// }).success(function (info) {// $scope.info = info;// });// 添加数据$scope.course = [{name: 'HTML', level: '初级', days: '10天'},{name: 'CSS', level: '初级', days: '12天'},{name: 'JAVASCRIPT', level: '高级', days: '18天'},]}]);// 后缀是通知操作系统应该使用哪个应用程序将它打开</script></body></html>
第11章其它
11.1 jQuery
在没有引入jQuery的前提下AngularJS实现了简版的jQuery Lite,通过angular.element不能选择元素,但可以将一个DOM元素转成jQuery对象,如果引提前引入了jQuery则angular.element则完全等于jQuery。
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>AngularJS jqLite</title><style>.box {width: 200px;height: 200px;border: 1px solid #CCC;}</style></head><body ng-app="App"><div class="box">有一些文字</div><script src="./libs/jquery.min.js"></script><script src="./libs/angular.min.js"></script><script>var App = angular.module('App', []);// 类似于 $('.box').css('color', 'red');// $('div')// jQuery 也可将一个原生DOM对象转成jQuery对象// angular.element() 接收的一个原生DOM对象// 会将这个原生DOM对象转成jQuery对象var box = document.querySelector('.box');angular.element(box).css('color', 'red');angular.element(box).animate({width: 400,height: 400}, 600);</script></body></html>
11.2 bower
基于NodeJS的一个静态资源管理工具,由twitter公司开发维,解决大型网站中静态资源的依赖问题。
1、依赖NodeJS环境和git工具。
2、npm install -g bower安装bower
3、bower search 查找资源信息
4、bower install  安装(下载)资源,通过#号可以指定版本号
5、bower info 查看资源信息
6、bower uninstall 卸载(删除)资源
7、bower init初始化,用来记录资源信息及依赖。
bower可以管理静态资源,并解决依赖关系。bower是基于nodejs的一个工具(使用nodejs开发的),要使用bower需要安装nodejs环境
nodejs就是一个软件,(普通安装即可)。避免安装在中文目录下。
安装完成后,并不会在桌面上创建图标,任务栏也不会有,只可以通过命令行来使用nodejs。
win+r 输入cmd 进入命令管理窗口。
输入 node -v验证nodejs是否正常 -前面有一个空格,显示版本号就是正常。
再输入 npm -v验证npm是否正常

                    
                

                
            
        
浙公网安备 33010602011771号