Typescript
Node
Npm
Angular/cli npm install -g @angular/cli
ng new my-app
ng serve --open
创建类
ng generate component heroes
创建服务
ng generate service hero
模块简介-----NgModule
///@NgModule() 装饰器是一个函数,它接受一个元数据对象,该对象的属性用来描述这个模块
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
@NgModule({
imports: [ BrowserModule ],/导入表
providers: [ Logger ],/本模块向全局服务中贡献的那些服务的创建器
declarations: [ AppComponent ],可声明对象表
exports: [ AppComponent ],/导出表
bootstrap: [ AppComponent ]应用的主视图,称为根组件
})
export class AppModule { }
组件简介
1-----------
export class HeroListComponent implements OnInit {
heroes: Hero[]; //属性,它储存着一个数组的英雄数据
selectedHero: Hero;//方法设置hero属性值
constructor(private service: HeroService) { }提供服务
ngOnInit() {----生命周期函数
this.heroes = this.service.getHeroes();/该组件会从服务获取英雄列表
}
selectHero(hero: Hero) { this.selectedHero = hero; }selectedHero方法
}
2---------装饰器写法
@Component({///@Component 装饰器会指出紧随其后的那个类(HeroListComponent )是个组件类,并为其指定元数据
selector: ‘app-hero-list’,//将组件HeroListComponent插入到中
templateUrl: ‘./hero-list.component.html’,//模板—该组件的 HTML 模板文件相对于这个组件文件的地址
providers: [ HeroService ]服务----当前组件所需的服务提供者的一个数组
})
export class HeroListComponent implements OnInit {//可以看到 HeroListComponent 只是一个普通类,完全没有 Angular 特有的标记或语法。 直到给它加上了 @Component 装饰器,它才变成了组件
/* . . . */
}
<h2>Hero List</h2>
<p><i>Pick a hero from the list</i></p>
<ul>
<li *ngFor="let hero of heroes" (click)="selectHero(hero)">
{{hero.name}}
</li>
</ul>
<app-hero-detail *ngIf="selectedHero" [hero]="selectedHero"></app-hero-detail>
ngFor 指令告诉 Angular 在一个列表上进行迭代。
{{hero.name}}、(click) 和 [hero] 把程序数据绑定到及绑定回 DOM,以响应用户的输入。
模板中的 标签是一个代表新组件 HeroDetailComponent 的元素
双向绑定
<input [(ngModel)]="hero.name">
注册服务
@Injectable({//顶级注册服务-----Injectable
providedIn: 'root',
})
@NgModule({
providers: [///组件注册服务--providers
BackendService,
Logger
],
...
})
@Component({
selector: ‘app-hero-list’,//该 selector 用于标识该组件。该选择器是当 Angular 组件在页面中渲染出 HTML 元素时使用的名字。按照惯例,Angular 组件选择器会以前缀 app- 开头,后跟组件名称
templateUrl: ‘./hero-list.component.html’,
providers: [ HeroService ]///组件注册服务–providers
})
应用架构
组件与模板
NgModules
路由与导航
依赖注入
响应式编程
生命周期钩子
可观察对象(Observable)和事件处理
Angular 自定义元素
表单
动画
*ngFor="let product of products”
*ngFor 是一个 “结构型指令”。结构型指令会通过添加、删除和操纵它们的宿主元素等方式塑造或重塑 DOM 的结构。带有星号 * 的指令都是结构型指令。
{{}} 允许你把属性值渲染为文本;
[] 则允许你在模板表达式中使用属性值。
*ngIf
()事件绑定是通过把事件名称包裹在圆括号 ( ) 中完成的
*ngFor
*ngIf
插值 {{}}
属性绑定 []
事件绑定 ()
生成新组建—angular generator
注意 @Component() 装饰器。这表明它下面的类是一个组件。它提供了有关该组件的元数据,包括它的选择器、模板和样式。
import { Component, OnInit } from '@angular/core';
import { Input } from '@angular/core'
@Component({
selector: 'app-product-alerts',
templateUrl: './product-alerts.component.html',
styleUrls: ['./product-alerts.component.css']
})
export class ProductAlertsComponent implements OnInit {
@Input() product;//@Input() 装饰器指出其属性值是从该组件的父组件商品列表组件中传入的
constructor() { }
ngOnInit() {
}
}
要包含这个新组件,只要像使用 HTML 元素一样使用它的选择器( app-product-alert )就可以了。
在组件类中,用 @Output() 装饰器和一个事件发射器 EventEmitter() 实例定义一个名为 notify 的属性
点击子组件触发父组件事件
子组件ts:@Output() 装饰器和一个事件发射器 EventEmitter() 实例定义一个名为 notify 的属性
import { Component } from '@angular/core';
import { Input } from '@angular/core'
import {Output, EventEmitter } from '@angular/core'
@Component({
selector: 'app-product-alerts',
templateUrl: './product-alerts.component.html',
styleUrls: ['./product-alerts.component.css']
})
export class ProductAlertsComponent {
@Input() product;
@Output() notify = new EventEmitter();
}
子组件html
<p *ngIf="product.price > 700">
<button (click)="notify.emit()">Notify Me</button>
</p>
父组件html:使用子组件,接收事件
<h2>Products</h2>
<div *ngFor="let product of products">
<h3>
<a [title]="product.name + 'details'">
{{product.name}}
</a>
</h3>
<p *ngIf="product.description">
Description:{{product.description}}
</p>
<button (click)= "share()">
Share
</button>
<app-product-alerts [product]="product" (notify)="onNotify()">
</app-product-alerts>
</div>
父组件ts:具体执行函数
import { Component } from '@angular/core';
import { products } from '../products';
@Component({
selector: 'app-product-list',
templateUrl: './product-list.component.html',
styleUrls: ['./product-list.component.css']
})
export class ProductListComponent {
products = products;
share() {
window.alert('The product has been shared!');
}
onNotify(){
window.alert('you')
}
}
路由配置
App.module.ts
@NgModule({
imports: [
BrowserModule,
ReactiveFormsModule,
RouterModule.forRoot([
{ path: '', component: ProductListComponent },
{ path: 'products/:productId', component: ProductDetailsComponent },
])
],
使用
<a [title]="product.name + 'details'" [routerLink] = "['/products',productId]">
{{product.name}}
</a>
管理数据
服务
在 Angular 中,服务是一个类的实例,它可以借助 Angular 的依赖注入系统来让应用中的任何一个部件都能使用它
ActivatedRoute 专门用于由 Angular 路由器加载的每个路由组件。它包含关于该路由,路由参数以及与该路由关联的其它数据的信息。
请求
src/app/app.module.ts
import { HttpClientModule } from '@angular/common/http';
@NgModule({
imports: [
BrowserModule,
HttpClientModule,
ReactiveFormsModule,
使用
import { HttpClient } from '@angular/common/http';
export class CartService {
items = [];
constructor(
private http: HttpClient
) {}
addToCart(product) {
this.items.push(product);
}
getItems() {
return this.items;
}
clearCart() {
this.items = [];
return this.items;
}
getShippingPrices() {
return this.http.get('/assets/shipping.json');
}
}
表单与用户输入
import { FormBuilder } from '@angular/forms';
注入服务-穿件表单数据模型
constructor(
private cartService: CartService,
private formBuilder: FormBuilder,
) {
this.checkoutForm = this.formBuilder.group({
name: '',
address: ''
});
}
[(ngModel)] 是 Angular 的双向数据绑定语法
虽然 ngModel 是一个有效的 Angular 指令,不过它在默认情况下是不可用的。
它属于一个可选模块 FormsModule,你必须自行添加此模块才能使用该指令
constructor(private heroService: HeroService) {}
这个参数同时做了两件事:1. 声明了一个私有 heroService 属性,2. 把它标记为一个 HeroService 的注入点。
异步请求赋值
import { Observable, of } from 'rxjs';
getHeroes(): Observable<Hero[]> {
return of(HEROES);
}
getHeroes(): void {
this.heroService.getHeroes()
.subscribe(heroes => this.heroes = heroes);
}
Angular 只会绑定到组件的公共属性。
从服务器获取数据
1.安装内存WEB API
npm install angular-in-memory-web-api --save
2.错误处理
import { catchError, map, tap } from ‘rxjs/operators’;
getHeroes(): Observable<Hero[]> {
return this.http.get<Hero[]>(this.heroesUrl)
.pipe(
catchError(this.handleError<Hero[]>(‘getHeroes’, []))
);
}
3.窥探
getHeroes(): Observable<Hero[]> {
return this.http.get<Hero[]>(this.heroesUrl)
.pipe(//管道
tap(_ => this.log(‘fetched heroes’)),
catchError(this.handleError<Hero[]>(‘getHeroes’, []))
);
}
使用 pipe() 方法来扩展 Observable 的结果,并给它一个 catchError() 操作符
.pipe(//管道
tap(_ => this.log(‘fetched heroes’)),//它们可以使用 RxJS 的 tap() 操作符来实现,该操作符会查看 Observable 中的值,使用那些值做一些事情,并且把它们传出来。 这种 tap() 回调不会改变这些值本身
catchError(this.handleError<Hero[]>(‘getHeroes’, []))
);
基础语法
一、组件与模板
(循环条件,插值数据类)
1.显示数据
{{}} 模板
2.使用变量赋值来对组件进行初始化
export class AppComponent {
title: string;
myHero: string;
constructor() {
this.title = 'Tour of Heroes';
this.myHero = 'Windstorm';
}
}
3.循环 *ngFor
<li *ngFor="let hero of heroes">
{{ hero }}
</li>
4.为数据创建一个类
ng generate class hero
//定义了一个类,具有一个构造函数和两个属性:id 和 name
export class Hero {
constructor(
public id: number,
public name: string) { }
}
使用类
heroes = [
new Hero(1, 'Windstorm'),
new Hero(13, 'Bombasto'),
new Hero(15, 'Magneta'),
new Hero(20, 'Tornado')
];
myHero = this.heroes[0];
5.条件
*ngIf="heroes.length>3”
二、(模板语法)
<script> 元素,它被禁用了,以阻止脚本注入攻击的风险。(实际上,<script> 只是被忽略了
1.插值 {{...}}
2.<button (click)="onSave($event)">Save</button>
3.<button *ngFor="let hero of heroes" (click)="deleteHero(hero)">{{hero.name}}</button>
4.<form #heroForm (ngSubmit)="onSubmit(heroForm)"> ... </form>
5.[target]="expression" 数据源到视图
6.(target)="statement" 视图到数据源
7.[(target)]="expression" 双向绑定
8.@Input() 装饰器 可传入的对象,父组件传入子组件,子组件接收数据定义的变量
9.NgSwitch 指令
二、生命周期
1.ngOnChanges()
2.ngOnInit()
3.ngDoCheck()
4.ngAfterContentInit()
5.ngAfterContentChecked()
6.ngAfterViewInit()
7.ngAfterViewChecked()
8.ngOnDestroy()