Angular 是一个开发平台。它能帮你更轻松的构建Web 应用。Angular 集声明式模板、依赖注入、端到端工具和一些最佳实践于一身,为你解决开发方面的各种挑战。
Angular了解
基础知识
- Augular CLI
- 模块
- 组件
- 模板
- 数据绑定
- 服务
- 路由
- HttpClient(基于RxJS响应编程)
优点
- 由于Google的目的是推出一个完整解决方案,所以官方默认提供的类库(比如routing,http,依赖性注入(DI)等)非常完整,无需自己选择。React的一大痛点就是选择太多导致在配置寻找组件和类库的过程中消耗太多精力,当然从另一方面看这也是其优势,选择众多且自由。
- 官方支持TypeScript(微软出品,是JavaScript的超集,是 JavaScript 的强类型版本)作为首选编程语言,使得开发脚本语言的一些问题可以更早更方便的找到。
- RxJS友好使得响应式编程在Augular2中变得极为容易(Google开发的框架依赖这么多的微软的产品,可见微软的转型还是很成功的)
- 支持NativeScript甚至ReactNative等进行原生Android/iOS应用开发(React支持React Native)
- 支持服务器端渲染(React也支持)
参考Link
Angular CLI
安装
$ npm i -g @angular/cli
输入ng -v
进行检查,控制台显示以下内容。
$~ ng -v
_ _ ____ _ ___
/ \ _ __ __ _ _ _| | __ _ _ __ / ___| | |_ _|
/ △ \ | '_ \ / _` | | | | |/ _` | '__| | | | | | |
/ ___ \| | | | (_| | |_| | | (_| | | | |___| |___ | |
/_/ \_\_| |_|\__, |\__,_|_|\__,_|_| \____|_____|___|
|___/
Angular CLI: 6.2.2
Node: 8.12.0
OS: darwin x64
Angular:
...
Package Version
------------------------------------------------------
@angular-devkit/architect 0.8.2
@angular-devkit/core 0.8.2
@angular-devkit/schematics 0.8.2
@schematics/angular 0.8.2
@schematics/update 0.8.2
rxjs 6.2.2
typescript 2.9.2
创建项目
$ ng new my-app
启动项目
$cd my-app
$ng serve --open
浏览器会自动打开http://localhost:4200/
项目目录结构
.
├── e2e 端到端测试目录
├── src 源文件(开发目录)
├── .editorconfig 编辑器统一风格工具配置文件
├── .gitignore git忽略文件
├── angular.json Angular CLI 脚手架配置
├── README.md 说明文件
├── package.json npm配置文件
├── tsconfig.json TypeScript编译器配置
└── tslint.json TypeScript语法检查器配置
.
├── src
│ ├── app 项目源文件( 重点 )
│ ├── assets 存放图片等资源文件
│ ├── browserslist 浏览器支持列表
│ ├── environments 运行环境配置:开发 or 生产
│ ├── favicon.ico 出现在浏览器标签上的应用图标。
│ ├── index.html 项目首页
│ ├── karma.conf.js karma 测试运行器的配置
│ ├── main.ts 项目入口
│ ├── polyfills.ts 导入JS,兼容老版本浏览器
│ ├── styles.css 全局样式
│ ├── test.ts 测试入口
│ ├── tsconfig.app.json TypeScript编译器配置
│ ├── tsconfig.spec.json 单元测试文件
│ └── tslint.json 额外的 TypeScript 语法检查器配置
.
├── app
│ ├── app.component.css app组件样式
│ ├── app.component.html app组件模板
│ ├── app.component.spec.css app组件单元测试
│ ├── app.component.ts app组件JS(TS)代码
│ ├── app.module.ts 根模块
TSlint 的配置
-
目的:修改为自己的代码风格
-
使用:
-
在
/tslint.json
中找到要修改的配置文件 -
将其添加到
src/tslint.json
文件中(或者直接在/tslint.json
中修改)
-
模块
-
每个应用至少有一个 Angular 模块,称为根模块,它通常命名为 AppModule。根模块的作用:启动应用。
-
模块是独立、封闭的。
-
模块之间的引用通过导入和导出来完成。
-
模块中包含的内容
- 组件
- 服务
- 指令
注意:这些内容必须在模块中配置后才有效
-
组件的组成部分
- 1 [组件名称].component.html
- 2 [组件名称].component.css
- 3 [组件名称].component.ts
- 单元测试文件(可选)[组件名称].component.spec.ts
装饰器
了解
-
装饰器是一个函数,又叫做注解。
-
作用:修饰紧随其后的类或属性。
-
装饰器是 JS 的一种语言特性,处于语法提案的stage2阶段,是一个试验特性。
Angular中装饰器
@NgModule装饰器
-
@NgModule
是Angular提供的装饰器。 -
用来告诉Angular将这个类当作模块来处理。
-
语法:
@NgModule({ 元数据对象 })
-
@NgModule
装饰器的元数据对象。
序号 | 元数据对象 | 解释 |
---|---|---|
1 | declarations | 该模块所拥有的组件 |
2 | imports | 该模块依赖的模块 e.g. BrowserModule |
3 | providers | 该模块所拥有的服务提供商 |
4 | bootstrap | 指定根组件,只有根模块需要该配置项Angular 创建它并插入 index.html 宿主页面。 |
5 | exports | 公开该模块其中的一部分,以便外部模块使用它们 |
@Component装饰器
序号 | 元数据对象 | 解释 |
---|---|---|
1 | selector | 选择器(组件名称),对应HTML中的组件名称 |
2 | template | 组件的内联模板e.g. template: ‘<div>template</div>’ |
3 | templateUrl | 组件模板文件的url,一般使用此项,很少使用template |
4 | styleUrls | 组件样式文件数组 |
- 一般
selector
的命名是以app-
为前缀
数据绑定
插值表达式
- 数据
app.component.html
<h1>Html </h1>
<h2></h2>
app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
// 数据
title = 'Test';
data = '2018-12-29';
}
- JS表达式
app.component.html
<h1></h1>
app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
// JS表达式
a = 1;
b = 2;
}
- 方法中返回的内容
app.component.html
<h1></h1>
app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
// 方法
fn() {
return 'This is fn'
}
}
- 元素的属性绑定
app.component.html
<h1 title=""></h1>
属性绑定
[href]=”属性绑定”
app.component.html
<a [href]="url">皮卡丘~</a>
app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
url = 'https://ws2.sinaimg.cn/large/006tNbRwly1fyml0ezzwtj30jg0jgq3o.jpg'
}
事件绑定
(click)=”事件绑定 ”
简单的事件绑定
app.component.html
<button (click)=“handleClick()” (mouseenter)=“hamdleMouseenter()”>点我啊</button>
app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
handleClick() {
console.log('click')
}
hamdleMouseenter() {
console.log('Mouseenter')
}
}
事件对象
app.component.html
<a [href]="url" (click)="handleClick()">百度~</a>
app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
handleClick() {
console.log('click')
};
}
点击页面会触发浏览器的默认行为,进行跳转。
app.component.html
<a [href]="url" (click)="handleClick($event)">百度aaaaaa</a>
app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
handleClick(e) {
// 阻止浏览器的默认行为
e.preventDefault()
console.log('事件触发了', e)
}
}
控制台会打印以下事件对象。
事件触发了 MouseEvent {isTrusted: true, screenX: -1786, screenY: 629, clientX: 57, clientY: 421, …}
双向数据绑定
[(ngModel)]=”双向数据绑定”
数据和试图直接形成相互的影响。数据改变,视图就会改变;视图改变,数据就会改变。
从语法看起来像是属性和事件的结合体。
app.component.html
<input type="text" [(ngModel)]="msg">
// 查看元素是否是双向改变
<h1></h1>
app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
msg = "Test"
}
会报错
compiler.js:1021 Uncaught Error: Template parse errors:
Can't bind to 'ngModel' since it isn't a known property of 'input'. ("
<br>
<br>
<input type="text" [ERROR ->][(ngModel)]="msg">
"): ng:///AppModule/AppComponent.html@16:19
at syntaxError (compiler.js:1021)
at TemplateParser.push../node_modules/@angular/compiler/fesm5/compiler.js.TemplateParser.parse (compiler.js:14830)
at JitCompiler.push../node_modules/@angular/compiler/fesm5/compiler.js.JitCompiler._parseTemplate (compiler.js:24018)
at JitCompiler.push../node_modules/@angular/compiler/fesm5/compiler.js.JitCompiler._compileTemplate (compiler.js:24005)
at compiler.js:23948
at Set.forEach (<anonymous>)
at JitCompiler.push../node_modules/@angular/compiler/fesm5/compiler.js.JitCompiler._compileComponents (compiler.js:23948)
at compiler.js:23858
at Object.then (compiler.js:1012)
at JitCompiler.push../node_modules/@angular/compiler/fesm5/compiler.js.JitCompiler._compileModuleAndComponents (compiler.js:23857)
需要导入模块,才可以使用。用inport
导入模块,用@NgModule
中的imports
导出模块。
app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
// 导入模块
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
// 导出模块
imports: [
BrowserModule,
FormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Angular语言服务
- Link
- 自动完成
- 错误检查
- 给出提示
- 内部导航
- 安装
- VSCode 安装 Angular Language Service
- webstorm 在看法模式下安装 ` @angular/language-service@6.0.0`
指令
指令是自定义标签,给现有的HTML标签添加特殊的标记。
指令分类
序号 | 指令 | 解释 |
---|---|---|
1 | 组件 | 拥有模板的指令 |
2 | 属性型指令 | 改变元素外观和行为的指令 |
3 | 结构型指令 | 添加和移除 DOM 元素改变 DOM 布局的指令 |
属性型指令
[ngClass] 动态添加或移除CSS类
多个CSS类
app.component.html
<h1 [ngClass]='classList'>ngClass</h1>
app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
classList = {
redColor : true,
fz: true
}
}
app.component.css
.redColor {
background-color: red;
}
.fz {
font-size: 16px;
}
更改app.component.ts
中的classList
中的true/false
可以看到页面元素class
的改变。
单个CSS类
app.component.html
<p [class.text]="isTest">添加/移除一个类</p>
app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
isTest = true;
}
app.component.ts
文件中isTest
为true
,则P标签中有test
的类,如果是false
,则没有test
这个类。
- 多个类是对象,只操作一个类是一个布尔值。
- 多个使用[ngClass] ,单个使用[class.text]。
[ngStyle] 动态设置内联样式
多个style
app.component.html
<p [ngStyle]="styleList">绿色,50px</p>
app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
styleList = {
color: 'green',
fontSize: '50px'
}
}
单个style
app.component.html
<p [style.color]="col">黄色</p>
app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
col = 'yellow'
}
结构型指令
*ngIf 控制元素的展示和隐藏
app.component.html
<h1 *ngIf="isShow">展示出来</h1>
app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
isShow = true
}
赋值给isShow
的表达式的值是false,那对应的元素将会从DOM中移除,否则生成一个新的元素插入DOM中。
app.component.html
<h1 [class.hidden]="isHidden">隐藏一下</h1>
app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
isHidden = true
}
- ngIf是根据表达式的值在DOM元素生成或移除一个元素。比较消耗性能。
- 频繁的切换展示一般是用CSS的方式。
*ngFor 重复器,遍历数据,批量生成元素
app.component.html
<p *ngFor="let item of nums"></p>
app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
nums = [1,2,3,4,5,6,6]
}
隔行变色
app.component.html
<p *ngFor="let item of colors; let i = index; let odd = odd" [class.red]="!odd"> </p>
app.component.ts
import { Component } from '@angular/core'
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
// 数据
colors = ['red', 'green', 'blue', 'pink']
}
*ngFor添加trackBy
- 目的:提升渲染对象数组的性能
- 语法:trachBy: trackBy方法名称
- 只有在渲染对象数组才有性能的问题,普通的数组是OK的。
app.component.html
<div>
<!-- 给 ngFor 指令添加 trackBy 提升渲染性能 -->
<!-- <p *ngFor="let item of colors; trackBy: trackById"></p>
<button (click)="fetchColors()">重新获取数据</button> -->
<!-- 演示普通数据有没有性能问题 -->
<button (click)="fetchData()">重新获取数据</button>
<ul>
<li *ngFor="let item of colors"></li>
</ul>
</div>
app.component.ts
import { Component } from '@angular/core'
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
// 数据
colors = ['red', 'green', 'blue', 'pink']
fetchData() {
setTimeout(() => {
this.colors = ['red', 'green', 'blue666', 'pink']
}, 500)
}
/* colors = [
{ id: 1, name: 'red' },
{ id: 2, name: 'green' },
{ id: 3, name: 'blue' }
]
fetchColors() {
setTimeout(() => {
this.colors = [
{ id: 1, name: 'red' },
{ id: 2, name: 'green 666' },
{ id: 3, name: 'blue' }
]
}, 500)
}
trackById(index, color) {
return color.id
} */
}
完
本文首次发布于 Azr的博客, 作者 @azrrrrr ,转载请保留原文链接.
原文链接: http://amor9.cn/2018/12/29/ng1/