@TOC
AngularJS简介
AngularJS是什么:
- Google开源的前端JS结构化框架
- 动态展示页面数据, 并与用户进行交互
- 官网
AngularJS特性和优点:
- 双向数据绑定
- 声明式依赖注入
- 解耦应用逻辑, 数据模型和视图
- 完善的页面指令
- 定制表单验证
- Ajax封装
与jQuery的比较:
- jQuery ①JS函数库 ②封装简化dom操作
- angular ①JS结构化框架 ②主体不再是DOM, 而是页面中的动态数据
AngularJS能做什么项目:
- 构建单页面(SPA)Web应用或Web App应用
- 应用: ①饿了吗: www.ele.me/home/ ②微信网页版: wx.qq.com/ ③知乎周报: zhuanlan.zhihu.com/Weekly ④后台管理应用: 阿里云, 土豆后台, 唯品会...
AngularJS使用
步骤:
- 引入AnaularJS
<script type='text/javascript' src="../../vendor/angular/angularjs.js"></script>
- 使用AngularJS ①导入angular.js, 并在页面中引入 ②在<html><body>中ng-app指令 ③定义ng-model='xxx'/{{xxx}}
- 例子: ①ng-app ②ng-model ③{{ }}
<!DOCTYPE html>
<html ng-app="">
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<input type="text" placeholder="用户名" ng-model="username">
<p>你输入的用户名为: {{username}}</p>
</body>
<script type='text/javascript' src="../../vendor/angular/angularjs.js"></script>
</html>
- 对比jQuery
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<script type="text/javascript" src="../../vendor/jQuery/jquery-1.11.1.js"></script>
<script type="text/javascript">
$(function () {
$('#name').keyup(function () {
var name = this.value;
$('#resultSpan').html(name);
});
});
</script>
<body>
<input type="text" name="username" id="name">
<p>你输入的用户名为:<span id="resultSpan">还未输入</span></p>
</body>
</html>
- 使用ng-inspector插件:ng-inspector.crx
数据绑定与依赖注入
双向数据绑定:
- 数据绑定: ①数据从一个地方A转移(传递)到另一个地方B, 而且这个操作由框架来完成 ②视图(View): 也就是我们的页面(主要是Andular指令和表达式) ③模型(Model) : 域对象(当前为$rootScope), 它可以包含一些属性或方法 ④当改变View中的数据, Model对象的对应属性也会随之改变 <1>数据从View==>Model : ng-model/ng-init ⑤当Model域对象的属性发生改变时, 页面对应数据随之更新 <1>数据从Model==>View : {{}}表达式
- 双向数据绑定:
①
数据可以从View流向Model, 也可以从Model流向View②ng-model是双向数据绑定, 而{{}}是单向数据绑定
依赖注入(DI):
依赖的对象被自动注入进来:Dependency Injection- 什么是依赖对象? ①完成特定功能的函数需要某个对象才能实现, 这个对象就是依赖对象
- 如何引入依赖对象? ①内部自己创建 : 不动态 ②全局变量 : 污染全局命名空间 ③形参引入依赖 : 依赖注入使用的方式
- 什么是依赖注入? ①定义函数时, 使用形参声明依赖对象变量, 在函数体中使用依赖对象(我们实现) ②函数调用时, 自动将创建好的依赖对象动态传入(框架实现) ③例子: 事件监听就使用了依赖注入, event就是依赖对象(event可以是任意名称)
- Angular中的依赖注入?
①形参必须是特定的名称, 否则Angular无法注入抛异常
MVC与MVMM
MVC模式:
- 通用:
①模型Model
<1>存储数据的实体模型
<2>操作数据的业务模型
②视图View
<1>显示数据
<2>响应用户操作, 与用户进行交互
③控制器Controller
<1>操作模型数据, 更新视图
<2>
View与Model之间的桥梁④结构图: - angular:
①View视图:
<1>html/css/directive/expression/filter
<2>显示Model的数据
<3>将数据同步到Model
<4>与用户交互
②Model模型:
<1>scope
<2>
储存数据的容器<3>提供操作数据的方法③Controller控制器: <1>controller <2>初始化Model数据<3>为Model添加行为方法④结构图:
M-V-VM模式:
-
MVVM是MVC的进化版, Angular使用的就是M-V-VM: ①在angular中MVVM模式主要分为四部分: <1>View:它专注于界面的显示和渲染,在angular中则是包含一堆声明式Directive的视图模板。 <2>Model:它是与应用程序的业务逻辑相关的数据的封装载体,它是业务领域的对象,Model并不关心会被如何显示或操作,所以模型也不会包含任何界面显示相关的逻辑。也就是Angular中的Service <3>
ViewModel:它是View和Model的粘合体,负责View和Model的交互和协作,它负责给View提供显示的数据,以及提供了View中Command事件操作Model的途径;也就是Angular中的scope<4>Controller:这并不是MVVM模式的核心元素,但它负责ViewModel对象的初始化,它将组合一个或者多个service来获取业务领域Model放在ViewModel对象上,使得应用界面在启动加载的时候达到一种可用的状态。 -
Model/模型: ①scope中的各个数据对象 ②数据模型
-
View/视图: ①html/css/directive/expression ②显示VM中的数据 ③与用户交互
-
ViewModel/视图模型: ①scope对象 ②View和Model的交互和协作 ③给View提供显示的数据 ④提供了View中Command事件操作Model的途径
作用域、控制器、模块
作用域(scope):
一个js实例对象, ng-app指令默认会创建一个根作用域对象($rootScope)- 它的属性和方法与页面中的指令或表达式是关联的
控制器(controller):
用来控制AngularJS应用数据的JavaScript 实例对象ng-controller : 指定控制器构造函数, Angular会自动new此函数创建控制器对象同时Angular还有创建一个新的域对象$scope, 它是$rootScope的子对象- 在控制器函数中声明scope形参, Angular会自动将\scope传入
- 每定义一个ng-controller指令, 内部就会创建一个新的作用域对象($scope), 并自动注入构造函数中,在函数内部可以直接使用$scope对象。
模块(module):
模块(module)也是一个对象- 创建模块对象:
angular.module('模块名', [依赖的模块])
- 通过模块添加控制器:
module.controller('MyController', function($scope){
//操作$scope的语句
})
- 使用模块对象: ①定义控制器 ②定义服务 ③定义指令 ④...
angular的整体设计也是多模块的:①ng:AngularJS的默认模块,包含AngularJS的所有核心组件。 ②扩展模块: <1>ngRoute:AngularJS是一套前端的MVC框架。那么,为了实现视图的中转,肯定会涉及到路由的概念。ngRoute即是AngularJS的路由模块。 <2>ngAnimate:AngularJS的动画模块,使用ngAnimate各种核心指令能为你的应用程序提供动画效果。动画可使用css或者JavaScript回调函数。 <3>ngAria:使用ngaria为指令注入共同的可达性属性和提高残疾人用户体验。 <4>ngResource:当查询和发送数据到一个REST 服务器时,使用ngResource模块。 <5>ngCookies:ngCookies模块提供了一个方便的包用于读取和写入浏览器的cookies。 <6>ngTouch:ngTouch模块提供触摸事件,方便的应用于移动触摸设备。它的实现是实现是基于jQuery移动触摸事件处理。 <7>ngSanitize:ngSanitize模块可安全地在你的应用程序中解析和操作HTML数据。 <8>ngMessages:AngularJS表单验证模块。ngMessages模块完美的实现了很多表单验证的常用功能,简化你的开发流程。
表达式和指令
表达式:
- 使用Angular表达式
①
语法: {{expression}}②作用: 显示表达式的结果数据 ③注意: 表达式中引用的变量必须是当前域对象所有的属性(包括其原型属性) - Angular表达式操作的数据
①
基本类型数据: number/string/boolean②undefined, Infinity, NaN, null解析为空串: "", 不显示任何效果 ③对象的属性或方法 ④数组 - 比较Angular表达与JS的表达式 ①Angular表达式写法与JS的表达式类同 ②与JS表达式不同,AngularJS 表达式可以写在HTML中。 ③与JS表达式不同,AngularJS 表达式不支持条件判断,循环及异常。 ④与JS表达式不同,AngularJS 表达式支持过滤器(后面专门讲)
表达式和语句的区别:
- 表达式:通常有一个返回值,可以放在任何需要值得地方,比如函数调用的参数,一个变量名,一个运算,
- 语句:通常表示一个完整的执行单位,一段完整的js可执行的代码,有的语句也可以用表达式来执行,叫做表达式语句。
- 区别:语句用封号结尾,有些语句我们没有加封号,比如console.log虽然我们没有加封号,但也是语句,因为js引擎会自动解析并且加上封号。js引擎在解析的时候会自动的加上封号。 ①特例:if语句,就不用加封号 可也是完整的语句。
指令:
- Angular指令:
①
Angular为HTML页面扩展的属性,标签②与Angular的Model交互,扩展页面的动态表现力 - 常用指令(一)
①
ng-app:指定模块名,angular管理的区域 ②ng-model:双向绑定,输入相关标签 ③ng-controller:指定控制器构造函数名,内部会自动创建一个新的子作用域(外部的) ④ng-init:初始化数据 ⑤ng-click:调用作用域对象的方法(点击时)可以传$event ⑥ng-repeat:遍历数组显示数据, 数组有几个元素就会产生几个新的作用域 <1>first, middle, even ⑦ng-bind:解决使用{{}}显示数据闪屏(在很短时间内显示{{}}) ⑧ng-show:布尔类型, 如果为true才显示 ⑨ng-hide:布尔类型, 如果为true就隐藏 - 常用指令(二)
①
ng-class:动态引用定义的样式 {aClass:true, bClass:false} ②ng-style:动态引用通过js指定的样式对象 {color:'red', background:'blue'} ③ng-mouseenter:鼠标移入监听, 值为函数调用, 可以传$event ④ng-mouseleave:鼠标移出监听, 值为函数调用, 可以传$event ⑤ng-include ⑥ng-blur ⑦ng-keydown ⑧ng-keyup ⑨ng-mouseover ⑩ng-mousemove ⑪ng-mouseout ⑫ng-mousedown ⑬ng-mouseup
过滤器
过滤器:
作用: 在显示数据时可以对数据进行格式化或过滤,滤器可以使用一个管道字符(|)添加到表达式和指令中。①单个--->格式化(将别的类型的数据转换为特定格式的字符串) ②多个----》格式化/过滤 ③不会真正改变被操作数据- {{express | 过滤器名:补充说明}}
常用过滤器:
currency:货币格式化(文本)number:数值格式化(文本)date:将日期对象格式化(文本)json:将js对象格式化为json(文本)lowercase :将字符串格式化为全小写(文本)
<div ng-app="myApp" ng-controller="personCtrl">
<p>姓名为 {{ lastName | lowercase }}</p>
</div>
uppercase :将字符串格式化全大写(文本)limitTo :从一个数组或字符串中过滤出一个新的数组或字符串 ①limitTo : 3 limitTo : -3orderBy :根据指定作用域属性对数组进行排序 ①{{[2,1,4,3] | orderBy}} 升序 ②{{[2,1,4,3] | orderBy:‘-’}} 降序 ③{{[{id:2,price:3}, {id:1, price:4}] | orderBy:'id'} id升序 ④{{[{id:2,price:3}, {id:1, price:4}] | orderBy:'-price'} price降序
<div ng-app="myApp" ng-controller="namesCtrl">
<ul>
<li ng-repeat="x in names | orderBy:'country'">
{{ x.name + ', ' + x.country }}
</li>
</ul>
</div>
filter :从数组中过滤返回一个新数组 ① {{[{id:22,price:35}, {id:23, price:45}] | filter:{id:'3'}} //根据id过滤 ② {{[{id:22,price:35}, {id:23, price:45}] | filter:{$:'3'}} //根据所有字段过滤
服务(Service)
服务(Service):
在 AngularJS 中,服务是一个函数或对象,可在你的 AngularJS 应用中使用。- AngularJS 中你可以创建自己的服务,或使用内建服务。(AngularJS 内建了30 多个服务。)
Angular的很多服务,在DOM中有对应的对象,那为什么不使用这些对象,而是要用服务呢?
- 因为这些服务可以获取到Angular应用声明周期的每一个阶段,并且和$watch整合,让Angular可以监控应用,处理事件变化。
- 普通的DOM对象则不能在Angular应用声明周期中和应用整合。
$location服务:
- $location 服务,它可以使用 DOM 中存在的对象,类似 window.location 对象,但 window.location 对象在 AngularJS 应用中有一定的局限性。
| -- | window.location | $location.service |
|---|---|---|
| 目的 | 允许对当前浏览器位置进行读写操作 | 允许对当前浏览器位置进行读写操作 |
| API | 暴露一个能被读写的对象 | 暴露jquery风格的读写器 |
| 是否在AngularJS应用生命周期中和应用整合 | 否 | 可获取到应用生命周期内的每一个阶段,并且和$watch整合 |
| 是否和HTML5 API的无缝整合 | 否 | 是(对低级浏览器优雅降级) |
| 和应用的上下文是否相关 | 否,window.location.path返回"/docroot/actual/path" | 是,$location.path()返回"/actual/path" |
$http 服务:
- $http 是 AngularJS 应用中最常用的服务。 服务向服务器发送请求,应用响应服务器传送过来的数据。
- 例子:
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $http) {
$http.get("welcome.htm").then(function (response) {
$scope.myWelcome = response.data;
});
});
$watch服务:
- $watch:持续监听数据上的变化,更新界面。
- 例子:
<div ng-app="myApp" ng-controller="myCtrl">
<b>请输入姓名:</b><br>
<b>姓:</b><input type="text" ng-model="lastName"><br>
<b>名:</b><input type="text" ng-model="firstName"><br>
<h1>{{ lastName + " " + firstName }}</h1>
<h2>{{ fullName }}</h2>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.lastName = "";
$scope.firstName = "";
//监听lastName的变化,更新fullName
$scope.$watch('lastName', function() {
$scope.fullName = $scope.lastName + " " + $scope.firstName;
});
//监听firstName的变化,更新fullName
$scope.$watch('firstName', function() {
$scope.fullName = $scope.lastName + " " + $scope.firstName;
});
});
</script>
angular控制器、服务和指令三者之间的关系:
服务负责从远端服务器抓取和存储数据。基于服务构建的控制器将为angular的作用域层次提供数据和功能。基于服务和控制器构建的指令将直接与文档对象模型(DOM)元素进行交互
provider(供应商)
provider(供应商):
provide服务负责告诉Angular如何创造一个新的可注入的东西:即服务。①服务会被叫做供应商的东西来定义,你可以使用$provide来创建一个供应商。 ②你需要使用provide中的provider()方法来定义一个供应商,同时你也可以通过要求\provide被注入到一个应用的config函数中来获得$provide服务。- 如图:
①$provide是一个服务,在Auto模块中
②这个服务下面有好多方法,是用来定义供应商
③而供应商是用来定义服务的,被注入来注入去的东西就是供应商们提供的服务了
- 下面是一个例子:
myMod.config(function($provide) {
$provide.provider('greeting', function() {
this.$get = function() {
return function(name) {
alert("Hello, " + name);
};
};
});
});
ngRoute 模块
简介:
- AngularJS是一套前端的MVC框架。那么,为了实现视图的中转,肯定会涉及到路由的概念。
ngRoute即是AngularJS的路由模块。 - ngRoute是一个AngularJS的模块。其不是在AngularJS的核心库当中。
- 在使用ngRoute的时候,实际上,我们是在应用的主模块中引入ngRoute模块并添加$routeProvider服务到主模块的config方法中来达到我们的目标。这与其他一些库的使用方式是类似的,如ng-grid。
在ngRoute中,主要有$route、$routeProvider、$routeParams三个服务项目。$routeProvider用于在主应用主模块的配置方法中。$route与$routeParams一般常见于控制器中。
使用:
- AngularJS 路由允许我们通过不同的 URL 访问不同的内容。
- 通过 AngularJS 可以实现多视图的单页 Web 应用(single page web application,SPA)。
- 通常我们的 URL 形式为 runoob.com/first/page,… Web 应用中 AngularJS 通过 #! + 标记 实现,例如:
http://runoob.com/#!/first
http://runoob.com/#!/second
http://runoob.com/#!/third
- 注意 Angular1.6 之前的版本是通过 # + 标记 实现路由。
- 当我们点击以上的任意一个链接时,向服务端请的地址都是一样的 (runoob.com/)。 因为 #!号之后的内容在向服务端请求时会被浏览器忽略掉。 所以我们就需要在客户端实现 #! 号后面内容的功能实现。AngularJS 路由就通过 #! + 标记 帮助我们区分不同的逻辑页面并将不同的页面绑定到对应的控制器上。
- 在以上图形中,我们可以看到创建了两个 URL: /ShowOrders 和 /AddNewOrder。每个 URL都有对应的视图和控制器。
- 接下来我们来看一个简单的实例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>AngularJS 路由实例 - 菜鸟教程</title>
<script src="https://cdn.bootcss.com/angular.js/1.7.0/angular.min.js"></script>
<script src="https://cdn.bootcss.com/angular.js/1.7.0/angular-route.min.js"></script>
</head>
<body ng-app='routingDemoApp'>
<h2>AngularJS 路由应用</h2>
<ul>
<li><a href="#!/">首页</a></li>
<li><a href="#!/computers">电脑</a></li>
<li><a href="#!/printers">打印机</a></li>
<li><a href="#!/blabla">其他</a></li>
</ul>
<div ng-view></div>
<script>
angular.module('routingDemoApp',['ngRoute'])
.config(['$routeProvider', function($routeProvider){
$routeProvider
.when('/',{template:'这是首页页面'})
.when('/computers',{template:'这是电脑分类页面'})
.when('/printers',{template:'这是打印机页面'})
.otherwise({redirectTo:'/'});
}]);
</script>
</body>
</html>
- 实例解析: ①载入了实现路由的 js 文件:angular-route.js。 ②包含了 ngRoute 模块作为主应用模块的依赖模块。 <1>angular.module('routingDemoApp',['ngRoute']) ③使用 ngView 指令。该 div 内的 HTML 内容会根据路由的变化而变化。 ③配置 routeProvider 用来定义路由规则。 <1>AngularJS 模块的 config 函数用于配置路由规则。通过使用 configAPI,我们请求把$routeProvider注入到我们的配置函数并且使用$routeProvider.whenAPI来定义我们的路由规则。 <2>$routeProvider 为我们提供了 when(path,object) & otherwise(object) 函数按顺序定义所有路由,函数包含两个参数: 1、第一个参数是 URL 或者 URL 正则规则。 2、第二个参数是路由配置对象。
路由设置对象:
- AngularJS 路由也可以通过不同的模板来实现。
- 路由配置对象语法规则如下:
$routeProvider.when(url, {
template: string,
templateUrl: string,
controller: string, function 或 array,
controllerAs: string,
redirectTo: string, function,
resolve: object<key, function>
});
- 参数说明:
①template:如果我们只需要在 ng-view 中插入简单的 HTML 内容,则使用该参数:
<1>
.when('/computers',{template:'这是电脑分类页面'})②templateUrl:如果我们只需要在 ng-view 中插入 HTML 模板文件,则使用该参数: <1>$routeProvider.when('/computers', { templateUrl: 'views/computers.html', });<2>以上代码会从服务端获取 views/computers.html 文件内容插入到 ng-view 中。 ③controller:function、string或数组类型,在当前模板上执行的controller函数,生成新的scope。 ④controllerAs:string类型,为controller指定别名。 ⑤redirectTo:重定向的地址。 ⑥resolve:指定当前controller所依赖的其他模块。
模块组件:
- 指令:
①
ngView 提供不同路由模板插入的视图层 - 供应者:
①
$routeProvider 提供路由配置 - 服务:
①
$routeParams 解析返回路由中带有的参数②$route 用于构建各个路由的url、view、controller这三者的关系
H5本地存储技术
cokkie:
- 作用:用于浏览器和服务器进行通信的。
- 特点: ①大小:4kb ②每次发送请求都携带,导致占用带宽 ③保存在浏览器端。 ④cokkie容易被截获,不安全。 ⑤生命周期: <1>会话cokkie:浏览器打开到关闭的过程 <2>人为设置cokkie:人为设置的时间
sessionStorage(会话存储):
- 生命周期:浏览器打开到关闭的过程。
- 大小:5M
- 保存的位置:浏览器端
- 方法: ①setItem(‘key’,value) ②getItem(‘key’) ③removeItem(‘key’)
localStorage(永久存储):
- 生命周期:永久,除非人为删除。
- 大小:5M甚至更大。
- 保存的位置:浏览器端
- 方法: ①setItem(‘key’,value) ②getItem(‘key’) ③removeItem(‘key’)