AngularJS学习笔记
一、AngularJS
AngularJS 是谷歌开源的前端 JS 结构化框架,官网
为了方便开发可安装 chrome 插件 ng-inspector
AngularJS 版本有 1.x、2.x、4.x,其中 1.x 是基于 JavaScript,2.x、4.x 是基于 typescript,4.x 是在 2.x 基础上扩展的
1、AngularJS 的特性和优点
(1)双向数据绑定
(2)声明式依赖注入
(3)解耦应用逻辑,数据模型和视图
(4)完善的页面指令
(5)定制表单验证
(6)Ajax 封装
2、AngularJS 和 jQuery 的比较
jQuery 是 JS 函数库,作用是封装简化 DOM 操作
angular 是 JS 结构化框架,主体不再是 DOM ,而是页面中的动态数据
3、AngularJS 应用场景
AngularJS 用于构建单页面(SPA)Web 应用或 Web App 应用,如饿了么、微信网页版、知乎周报、后台管理应用(如阿里云、土豆后台、唯品会等)
单页面应用 SPA(Single Page Application)特点:
— 将所有活动局限于一个页面
— 当页面中有部分数据发生变化时不会刷新整个页面,而是局部刷新
— 利用的是 ajax 技术、路由
二、AngularJS 语法
1、hello world
例子:输入框中输入的文本在下方实时显示
<body ng-app>
<input type="text" ng-model="username">
<p><span>{{username}}</span></p>
<script src="./angular-1.2.29/angular.js"></script>
</body>
ng-app 指令:告诉 angular 核心它管理当前标签所包含的整个区域,并会自动创建 $rootScope 根作用域对象
ng-model 指令:ng-model 指向属性名,将当前输入框的值与当前作用域对象关联(属性名:属性值),并作为当前作用域对象($rootScope)的属性
{{ }}
表达式:显示数据,从当前作用域对象的指定属性名上获取,只能用于显示不能操作更改
2、双向数据绑定
数据绑定:数据从一个地方 A 转移(传递)到另一个地方 B,且该操作由框架完成
双向数据绑定:数据可以从 View(视图层)流向 Model(模型),也可以从 Model 流向 View
— 视图(View):就是页面(主要是 angular 指令和表达式)
— 模型(Model):作用域对象,它可以包含一些属性或方法
— 当改变 View 中的数据,Model 对象的对于属性也会随之改变:ng-model 指令数据从 View ==> Model
— 当 Model 域对象的属性发生改变时,页面对象数据随之更新:{{ }}
表达式数据从 Model ==> View
— ng-model 是双向数据绑定(View <==> Model),而 {{ }}
是单向数据绑定(Model ==> View)
ng-init 用来初始化当前作用域变量,是单向数据绑定(View ==> Model)
例子
两个输入框,每个输入框下显示输入框中的文本,更改其中一个输入框,另一个输入框以及两个输入框下的文本都改变,初始时输入框和文本为 “xxx”
<body ng-app ng-init="username='xxx'">
<input type="text" ng-model="username">
<p>{{username}}</p>
<input type="text" ng-model="username">
<p>{{username}}</p>
<script src="./angular-1.2.29/angular.js"></script>
</body>
3、依赖注入
依赖对象:完成某个特定功能需要某个对象才能实现,该对象就是依赖对象
依赖注入:依赖的对象以形参的形式被注入进来使用,这种方式就是声明式依赖注入
注意:形参必须是特定的名称,否则 angular 无法注入,抛出异常
angular 的 $scope
对象就是依赖对象,并且是依赖注入的形式进行使用
回调函数的 event 就是依赖对象,回调函数有形参就是依赖注入
三、三个重要对象
1、作用域对象与控制器对象
作用域对象
作用域对象是一个 js 实例对象,ng-app 指令默认会创建一个根作用域对象($rootScope)
它的属性和方法与页面中的指令或表达式是关联的
控制器对象
控制器对象用来控制 AngularJS 应用数据的实例对象的
ng-controller:指定控制器构造函数,Angular 会自动 new 此函数创建控制器对象
同时 Angular 还有创建一个新的作用域对象 $scope,它是 $rootScope 的子对象
在控制器函数中声明 $scope 形参,Angular 会自动将 $scope 对象传入
<body ng-app ng-init="age=12">
<div ng-controller="MyController">
<input type="text" ng-model="firstName">
<input type="text" ng-model="lastName">
<p>{{firstName + '-' + lastName}}</p>
<p>{{getName()}}</p>
<p>{{age}}</p>
</div>
<script type="text/javascript" src="./angular-1.2.29/angular.js"></script>
<script type="text/javascript">
//老版本 angular 生成作用域对象的方式
function MyController($scope){ //形参必须是$scope
$scope.firstName = 'aa';
$scope.lastName = 'bb';
$scope.getName = function(){
return this.firstName + ' ' + this.lastName; //也可以是 $scope.firstName + ' ' + $scope.lastName
}
}
</script>
</body>
2、模块与控制器对象
angular.module
可在全局创建、注册、获取 Angular 模块,所有模块(angular 核心或第三方)都必须使用这个机制注册才能在应用中生效
模块对象可链式调用,模块对象.controller
返回值是模块对象
<body ng-app="MyApp">
<div ng-controller="MyController1">
<input type="text" ng-model="empName">
<p>{{empName}}</p>
</div>
<div ng-controller="MyController2">
<input type="text" ng-model="empName">
<p>{{empName}}</p>
</div>
<script type="text/javascript" src="./angular-1.5.5/angular.js"></script>
<script type="text/javascript">
//创建模块对象
var myModule = angular.module('MyApp',[]);
//生成作用域对象(新版本 angular)
myModule.controller('MyController1',function($scope){ //隐式声明依赖注入
$scope.empName = 'aaa'
})
myModule.controller('MyController2',function($scope){
$scope.empName = 'bbb'
})
//或使用链式调用
//angular.module('MyApp',[])
// .controller('MyController1',function($scope){ //隐式声明依赖注入
// $scope.empName = 'aaa'
// })
// .controller('MyController2',function($scope){
// $scope.empName = 'bbb'
// })
</script>
</body>
注意:当代码压缩时,$scope 会被 abcd等字母代替,导致 angular 解析不了,因此需要使用显式声明依赖注入,开发时需要使用该方式
angular.module('MyApp',[])
.controller('MyController1',['$scope',function($scope){ //显式声明依赖注入
$scope.empName = 'aaa'
}])
.controller('MyController2',['$scope',function($scope){
$scope.empName = 'bbb'
}])
四、表达式
{{表达式}}
用于显示表达式的结果数据
表达式中引用的变量必须是当前作用域对象有的属性(包括其原型属性)
可操作的数据有:
— 基本类型数据:number、string(需加引号)、boolean
— undefined、Infinity、NaN、null解析为空串,不显示任何效果
— 对象的属性或方法
— 数组
五、指令
Angular 指令是 Angular 为 HTML 页面扩展的自定义标签属性或标签
Angular 指令与 Angular 的作用域对象(scope)交互,扩展页面的动态表现力
常用指令有
ng-app:指定模块名,angular 管理的区域
ng-model:双向数据绑定,输入相关标签
ng-init:初始化数据
ng-click:点击时调用作用域对象的方法
ng-controller:指定控制器构造函数名,内部会自动创建一个新的子作用域(外部的)
ng-bind:解决使用 {{ }}
显示数据闪屏(在很短时间内显示 {{ }}
)
ng-repeat:遍历数组显示数据,数组有几个元素就会产生几个新的作用域,自动携带的属性有 $index(下标)、$first(布尔值)、$last(布尔值)、$middle(布尔值)、$odd(布尔值,下标为奇数时为 true)、$even(布尔值)
ng-show:布尔类型,为 true 才显示
ng-hide:布尔类型,为 true 就隐藏
<body ng-app="MyApp">
<div ng-controller="MyController">
<div>
数量:<input type="number" ng-model="count">
价格:<input type="number" ng-model="price">
<button ng-click="getTotalPrice()">计算</button>
<p>{{totalPrice}}</p>
</div>
<div>
<ul>
<li ng-repeat="person in persons">
{{$index}}---{{$even}}---{{person.username}}---{{person.age}}
</li>
</ul>
</div>
<div>
<p>{{123}}</p>
<p ng-bind="123"></p><!--与上行使用表达式{{}}等价-->
aaa
aaa
ng-class:动态引用定义的样式 {aClass:true, bClass:false}
ng-style:动态应用通过 js 指定的样式对象 `ng-style="{color:'red', background:'green'}"` 或 `ng-style="作用域变量"`
ng-click:点击监听,值为函数调用,可以传 $event
ng-mouseenter:鼠标移入监听,值为函数调用,可以传 $event
ng-mouseleave:鼠标移出监听,值为函数调用,可以传 $event
-
{{person.username}}---{{person.age}}
</li>
</ul>
</div>
<script type="text/javascript" src="./angular-1.5.5/angular.js"></script>
<script type="text/javascript">
angular.module('MyApp',[])
.controller('MyController',['$scope',function($scope){
$scope.myStyle = {
background: 'red'
}
$scope.enter = function(){
this.myStyle.background = 'green';
}
$scope.leave = function(){
this.myStyle.background = 'red';
}
$scope.persons = [
{username:'a',age:12},
{username:'b',age:12},
{username:'c',age:12},
]
}])
</script>
</body>
其他
1、开发的两种方式
(1)命令式
更加注重的是执行的过程
(2)声明式
更加注重的是执行的结果,至于中间是如何执行的并不关心
声明式是对命令式的局部包装
命令式如同考试的解答题,声明式如同选择填空题
例子:对数组中的每个元素加 10
var arr = [1,2,3,4,5]
//命令式
var arr1 = []
for(var i = 0; i < arr.length; i++){
var value = arr[i] + 10;
arr1.push(value);
}
console.log(arr1);
//声明式
var arr2 = arr.map(function(item, index){
return item + 10;
})
console.log(arr2);
2、多选框绑定数据
多选框绑定的数据会是布尔值,表示是否选中
<body ng-app="MyApp">
<div ng-controller="MyController">
<div ng-repeat="todo in todos">
<input type="checkbox" ng-model="todo.isChecked">
<span>{{todo.name}}</span>
</div>
</div>
<script type="text/javascript" src="./angular-1.5.5/angular.js"></script>
<script type="text/javascript">
angular.module('MyApp',[])
.controller('MyController',['$scope',function($scope){
$scope.todos = [
{name:'aa', isChecked: false},
{name:'bb', isChecked: true},
{name:'cc', isChecked: false}
]
}])
</script>
</body>