Angular JS赶快学起来(上)
我将分为上下两篇来介绍Angular JS,废话不多说,直接看内容吧...
一:首先,什么是Angular JS呢?
- 一个前端框架,提供一种无DOM操作的编程方式,在前端页面中引入了传统在后台开发中使用的一些思想,增强代码的结构和可维护性
- 一个功能非常完备的前端框架,通过增强HTML的方式提供一种便捷开发Web应用程序的方式
- 其核心特点就是几乎无任何DOM操作,让开发人员的精力和时间全部集中于业务
- MVC的特性增强了代码的结构和可维护性,应对需求的变化做出最小的改动
二:那我们为什么要使用Angular呢?
- 总结成一句话就是:为了使用更少的代码,实现更强劲的功能
+ 很多操作都需要dom操作,但是angular中没有那么多的dom操作,这是因为angular帮我们封装了,减少了我们开发人员的dom操作
+ 一般在angular中就不会出现jquery了,因为这两种思想正好是相悖的。
+ 它的意义是革命性的,这就像从手工业转为机械工业一样,以前很多东西都是我们自己手动去做,现在我们有了gulp,webpack这些自动化构建工具。
-相关网站
- AngularJS 1.x 官方网站
+ https://angularjs.org/
- AngularJS 2.x 官方网站
+ https://angular.io/
- Google Material Design for Angular
+ https://material.angularjs.org
- Angular UI(Angular最大的第三方社区)
+ http://angular-ui.github.io/
- AngularJS中文社区
+ http://www.angularjs.cn/
- AngularJS中文社区提供的文档(不用FQ)
+ http://docs.angularjs.cn/api
+ http://www.apjs.net/
三:什么是 SPA?
- single page application的缩写
- 单页应用程序
- 原理就是:通过监视hashchange事件,根据不同的url中的锚点值,去动态的发送ajax请求去请求数据(简单的说就是不会看到页面刷新)
+ 网站实例:music.163.com(可以点开这个网站看看,就能深刻的理解SPA了)
四:SPA的优点
- 响应效果好,体验好
- 重用资源
- 方便统一控制和代码重用,不想访问应用了,在入口的控制一下就可以。
五:Angular快速开始
<body ng-app>
<div>
<input type="text" ng-model="hello">
<!-- ng-model是用于建立数据模型中的hello属性到当前元素的value上 -->
<h1>Hello {{hello}}</h1>
<!-- {{}} 表达式作用类似于模版引擎中的输出(也可以自动同步) -->
</div>
<div>
<input type="text" ng-model="user.name">
<h1>Hello {{user.name}}</h1>
</div>
<script src="node_modules/angular/angular.js"></script>
</body>
@@使用AngularJS的流程
1. 借助npm下载到本地
2. 在HTML代码中引入Angular.js包
3. 在JS代码中通过`angular.module(‘myApp‘, [])`注册一个模块
4. 在HTML代码中将刚刚定义的模块通过`ng-app="myApp"`指令的方式作用到一个特定的元素上
5. 根据当前页面的情况(业务块)划分控制器
6. 在HTML代码中将刚刚定义的控制器通过`ng-controller="ControllerName"`作用到特定的元素上
7. 建模(根据界面原型抽象一个数据模型)得到一个视图模型(ViewModel)
8. 在JS代码中通过`$scope`暴露需要提供到页面的数据成员
9. 在HTML代码中将刚刚暴露出来的数据通过类似`ng-model/{{}}/ng-click`之类的指令绑定到特定的元素上
支持的类型
- 数字 {{ 50 + 100 }}
- 字符串 {{ ‘ni‘ + ‘hao‘ }}
- 对象 {{ zhangsan.name }}
- 数组 {{ students[60] }}
10. 在JS中完成业务逻辑(还可以展开)
@@Angular 核心概念
- 模块化
- MVC - 思想
- 指令
- 双向数据绑定
@@angular.module(模块)
@作用
- 通过模块对页面进行业务上的划分
- 将重复使用的指令或者过滤器之类的代码做成模块,方便复用
- 注意必须指定第二个参数,否则变成找到已经定义的模块
@语法
- 根据不同的功能划分不同的模块。
- 创建一个模块
- 语法: `angular.module(‘模块名‘,[])`
+ 第二个参数是个数组,这个数组里的每一个元素,是我们当前模块依赖的其他模块
+ 注意: 即便我们不依赖其他的模块,也需要传递一个空数组
因为如是不传第二个参数的话,这个方法的作用就会变为获取一个名为"模块名"的模块对象
+ `angular.module(‘myApp‘)`,是获取一个名为myApp的模块对象。
+ 我们需要给ng-app指令一个属性值,这个值就是我们创建的模块名:
* 告诉anuglar,现在由我们自己创建的这个模块来管理页面。
@@angular.controller(控制器)
@作用
- 为应用中的模型设置初始状态
- 通过$scope对象把数据模型或者函数行为暴露给视图
- 监视模型的变化,做出相应的动作
@语法
- 控制器是通过模块对象来创建的:
- 语法:
`var app = angular.module(‘模块名‘,[])`
`app.controller(‘控制器的名字‘,function($scope){
// 在这个function里写我们具体想要执行的代码
// $scope 就是用来存储我们的数据模型.
})`
- 我们需要在页面上使用了数据模型的元素父级元素上加上ng-controller指令,并给这个指令一个属性值,这个值就是我们创建的控制器名字。
@@双向数据绑定(双向数据绑定)
- 页面文本框的值改变,导致数据模型的值发生改变,
- 数据模型的值的改变,反过来导致页面文本框的值的改变,这种相互影响的关系,我们起了个名词,叫作双向数据绑定。
- ng-model = ""
@@单向数据绑定
- 只能一数据模型的值改变,导致页面值的改变;
@@MVC 思想
@什么是 MVC 思想
- 将应用程序的组成划分为三个部分:Model View Controller
+ 模型:数据处理
+ 视图:以友好的方式向用户展示数据
+ 控制器:业务逻辑处理
- 控制器的作用就是初始化模型用的;
- 模型就是用于存储数据的,做一些业务逻辑的操作。
- 视图用于展现数据
@用MVC构建应用的优势
- 剥离开视图和逻辑之间的关系,无论怎么修改dom操作都不用修改业务逻辑代码
六:指令
- 在 AngularJS 中将前缀为 ng- 这种属性称之为指令,其作用就是为 DOM 元素调用方法、定义行为绑定数据等
- 简单说:当一个 Angular 应用启动,Angular 就会遍历 DOM 树来解析 HTML,根据指令不同,完成不同操作
@@指令标准属性的问题
- ng-xxx 的属性本身并不是HTML标准中定义的属性
- 很多情况下语法校验是无法通过的,但是浏览器有容错性。
- HTML5 允许扩展的(自制的)属性,以 data- 或者x- 开头。
- 在 AngularJS 中可以使用 data-ng- 来让网页对 HTML5 有效。
- ng-和data-ng-二者效果相同。
1. 内置指令
@ ng-app
- ng-app 指令用来标明一个 AngularJS 应用程序
- 标记在一个 AngularJS 的作用范围的根对象上
- 系统执行时会自动的执行根对象范围内的其他指令
- 可以在同一个页面创建多个 ng-app 节点(不推荐)
- 创建多个ng-app时,默认只能执行第一个,后面的需要手动引导:angular.bootstrap()
如:angular.bootstrap(document.getElementById(‘div1‘), [‘module1‘]);
- 标记的范围尽可能小,这样可以减少遍历的dom元素,主要为了性能
@自动引导
- 在angular中一个页面中只能有一个ng-app指令,这是单页面应用程序的入口,这属于自动引导
@手动引导
- 如果想在一个页面中使用多个ng-app指令,需要进行手动引导
如:angular.bootstrap(document.getElementById(‘div1‘), [‘module1‘]);
@ 多模块使用标准写法
如:angular.module(‘mainModule‘, [‘module1‘, ‘module2‘]);
// 应用中的多模块应该使用主模块去载入
@@ng-model
- 用于建立界面上的元素到数据模型属性的双向数据绑定
- 一般情况绑定到元素的value属性上
- 但是在checkbox之类的表单元素会有不同
@@ng-bind
- ng-bind和表达式效果相同,不过能防止闪动一下页面
- ng-bind上来是没有东西的,需要通过viewmodel或者ng-init初始化绑定的值
代码:
...
<h1 ng-bind="name"></h1>
...
var myModule=angular.module("myModule",[‘ngSanitize‘]);
myModule.controller("myController", [‘$scope‘,function ($scope) {
$scope.name="<span>jim</span>";
}])
@@ ng-bind-html
- 可以把字符串中的html在页面中直接展示
- 不过在使用的时候会报不安全问题,缺少引用的文件,需要引用第三方的包才能实
现安全输出浏览器自动也会帮你处理一些安全问题的,不会执行或者输出不安全的代码,
在开发的过程中要有意识的考虑攻击问题,想一下输出的会不会是可执行的代码,需要编 码后再呈现。
@@ng-repeat
- 循环输出页面内容
- 数据源是数组
```
var data = [
{ id: 1, name: ‘张三1‘, age: 18, gender: true },
{ id: 2, name: ‘张三2‘, age: 28, gender: true },
{ id: 3, name: ‘张三3‘, age: 38, gender: true },
{ id: 4, name: ‘张三4‘, age: 48, gender: true },
{ id: 5, name: ‘张三5‘, age: 58, gender: true },
];
```
```
<ul ng-controller="MainController">
<li ng-repeat="item in data">
<p>
<span>{{item.id}}</span>
<span>{{item.name}}</span>
<span>{{item.age}}</span>
</p>
</li>
</ul>
```
- 数据源是对象
```
var data = {
1: { name: ‘张三1‘, age: 11, gender: true },
2: { name: ‘张三2‘, age: 12, gender: true },
3: { name: ‘张三3‘, age: 13, gender: true },
4: { name: ‘张三4‘, age: 14, gender: true },
5: { name: ‘张三5‘, age: 15, gender: true },
};
```
```
<ul ng-controller="MainController">
<li ng-repeat="(id, item) in ps track by $index">
<p>
<span>{{id}}</span>
<span>{{item.name}}</span>
<span>{{item.age}}</span>
</p>
</li>
</ul>
```
- $index
+ ng-repeat中的索引
@@ ng-class
- 决定某个样式是否添加
- ng-class={classname1:是否添加,classname2:是否添加}
代码:
...
<style>
.red{
color:red;
}
</style>
</head>
<body ng-app="myModule" ng-controller="myController">
<input type="text" ng-model="search"/>
<ul>
<li ng-repeat="item in data" ng-class="{red:search&&item.name.startswith(search)}">
{{item.name}}
</li>
</ul>
</body>
<script src="./node_modules/angular/angular.js"></script>
<script>
var myModule=angular.module("myModule",[]);
myModule.controller("myController", [‘$scope‘,function ($scope) {
$scope.search="";
$scope.data=[
{ id: 1, name: ‘张三‘, age: 11, gender: true },
{ id: 2, name: ‘李二‘, age: 12, gender: true },
{ id: 3, name: ‘李三‘, age: 13, gender: true },
{ id: 4, name: ‘王二‘, age: 14, gender: true },
{ id: 5, name: ‘王三‘, age: 15, gender: true },
{ id: 6, name: ‘张二‘, age: 15, gender: true }
]
}])
@@ $apply
- 异步操作中的数据绑定不能及时监听到,让页面渲染,所以需要手动调用一下
代码:
<body ng-app="myModule" ng-controller="myController">
<div ng-show="loading">正在加载中</div>
</body>
<script src="./node_modules/angular/angular.js"></script>
<script>
var myModule=angular.module("myModule",[]);
myModule.controller("myController", [‘$scope‘,function ($scope) {
$scope.loading=true;
//模拟异步操作 在异步操作中的赋值不能被angular监听到,解决:手动调用$apply
//方法触发模型的重新渲染
setTimeout(function () {
$scope.loading=false;
},4000)
}])
@@ng-cloak
- 自动给页面元素添加dispaly:none属性,当页面渲染完毕后自动删除
- 最后你会发现直接把angularjs引用到最上面就不会有闪屏现象了,因为angularjs在页面 渲染的时候已经执行了
@@ ng-show/ng-hide/ng-if
- ng-show和ng-hide是控制页面是否显示
- ng-if的作用是控制是否存在这个dom元素,如果值等于false会把页面中的元素注释
@@ ng-switch
- 根据value值决定页面中的哪部分显示
@@ ng-src
- 用于解决当链接类型数据绑定时候造成的加载问题
- ng-src指令会自动帮你把属性值赋值给src属性,类似于懒加载中的效果一样
@@@其他常用指令
- ng-checked:
+ 单选/复选是否选中,只是单向绑定数据
- ng-selected:
+ 是否选中,只是单向绑定数据
- ng-disabled:
+ 是否禁用
- ng-readonly:
+ 是否只读
2. 自定义指令
- 指令增强了 HTML,提供额外的功能
- 内置的指令基本上已经可以满足我们的绝大多数需要了
- 少数情况下我们有一些特殊的需要,可以通过自定义指令的方式实现
@@ 普通指令
- 语法
```
<div hello-world></div>
<hello-world></hello-world>
```
```
angular.module(‘myModule‘, [])
.controller(‘HelloController‘, [‘$scope‘, function($scope) {
$scope.customer = {
name: ‘张三‘,
address: ‘上海‘
};
}])
.directive(‘helloWorld‘, [‘$log‘, function($log) {
// 此处为指令工厂 工厂应该返回指令对象
return {
template: ‘Name: {{customer.name}} Address: {{customer.address}}‘
};
}])
```
@@ 内容转置
- 把页面指令中的内容转置到指令中template中有ng-transclude指令的innerhtml中
- transclude属性:bool
- replace属性:bool 是否替换指令的dom元素
@@ 模板抽取
- template属性是不支持html代码段换行的,所以把大量的html写在里面结构会很不清晰,我们可以借助templateUrl属性抽离模板页面
- templateUrl属性就是以异步请求的方式去请求模板
@@ 指令的独立作用域
- 每个模块中的$scope都有自己的独立作用域
- scope属性:object,可以实现指令的独立作用域
@@ 作用域的属性传递
- 语法
```
scope: {
title: ‘@‘,
type: ‘@‘
},
```
```
<div class="row">
<div class="col-md-4">
<bs-panel type="default" title="panel1">
aaaaaaaaaaaaaaaaaaaaa
</bs-panel>
</div>
<div class="col-md-4">
<bs-panel type="default" title="panel2">
aaaaaaaaaaaaaaaaaaaaaa
</bs-panel>
</div>
</div>
```
- @ 指的是当前属性在执行时会去取指令作用到的DOM元素的title
@@ 自定义指令的类型
- restrict属性可以定义指令的使用类型
1. E:Element(元素)
2. A:Attribute(属性)
3. C:Class(类名)
4. M:Comment(注释)
- 注意:在定义指令应该使用驼峰命名法,使用指令时应该使用的是全小写字母中划线分割的方式,注释的方式没有办法使用转置等功能
@@ 指令中的dom操作
- link属性是指令中可以操作dom元素的地方(css,属性,innerHtml)
```
link: function($scope, element, attributes) {
// Scope是指令的scope,element是指令作用的dom元素,attributes是属性
// 我们经常说的dom操作指的是css,属性,innerhtml这些操作
element.on(‘mouseenter‘, function() {
element.css(‘backgroundColor‘, ‘red‘);
}).on(‘mouseleave‘, () => {
element.css(‘backgroundColor‘, ‘transparent‘);
});
}
```