angular常用指令一览
ng generate component example // 生成组件带有模版(简写 ng g c example)
ng generate component example -it // 生成内联模版(不会单独生成html文件)
ng generate module my-module // 生成一个新模块
ng generate directive my-directive // 生成一个新指令
ng generate pipe my-pipe // 生成一个新管道
ng generate service my-service // 生成一个新服务
ng generate route my-route // 生成一个新路由
ng generate class my-class // 生成一个简易的模型类
安装angular-cli 脚手架,如果npm比较慢,请使用淘宝镜像
npm install -g @angular/cli
npm i -g @angular/cli@1.1.0 //安装指定版本的angular脚手架
//更换npm源
npm config set registry https://registry.npm.taobao.org
//验证是否配置成功
npm config get registry
//npm官方源 https://registry.npmjs.org
//安装cnpm,更换npm的源或者使用cnpm,二选一
npm install -g cnpm --registry=https://registry.npm.taobao.org
//注意:低版本npm3.10.9安装低版本angular/cli@1.1.0
//需要把镜像源改回registry.npmjs.org;这样才能安装,问题推测是淘宝镜像源里面没有这个版本
创建一个项目
ng new myAngular // 创建一个项目,注意在git自带的brash 里面创建,可能不会显示引导步骤
ng new myAngular --skip-install // 不用安装依赖包
ng new myAngular -si // 上一句的缩写
ng new myAngular --routing // 创建一个带路由的
ng new myAngular --strict // 使用更严格的 typescript 编译选项
组件结构
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
template: `<h1>{{title}}</h1>`
})
export class AppComponent {
title = 'myAngular';
constructor() {}
}
模块结构
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
@NgModule({
declarations: [ AppComponent ],
imports: [ BrowserModule ],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
创建组件命令
ng generate component 组件名
ng g c 组件名 //上面命令的缩写
ng g c 组件名 -it //生成内联模板,便于测试
基本绑定
msg:string = "文本";
bgClass:string = "bgRed";
<span>{{msg}}<span>
<div class="{{bgClass}}"></div>
public placeholder:string = "Dan"
public index:number = 0
<input type="text" [value]="placeholder"></input>
<input type="text" value="{{placeholder}}"></input>
<input type="text" [value]="{{placeholder}}"></input>
<input type="text" bind-value="placeholder"></input>
<input type="text" [attr.data-index]="index"></input>
<tr><td [attr.colspan]="2">Attribute的方式绑定</td></tr>
<tr><td [colSpan]="2">Property的方式绑定</td></tr>
htmlStr:string = "<h1>标题</h1><script>location.href="www.baidu.com"</script>"
<div [innerHtml]="htmlStr"></div>
public successClass:string = "text-success ..."
public hasError:Boolean = true;
public messageClasses: Object = {
"text-success": false,
"text-danger": true
}
public arrClass = ['aa','bb']
<h2 class="aa" [class]="successClass"> 标题</h2> //绑定值是字符串
<h2 class="aa" class="{{successClass}}"> 标题</h2>
<h2 class="aa" [attr.class]="successClass"> 标题</h2>
<h2 [class.text-danger] = "hasError">标题</h2>
<h2 [class]="messageClasses">标题</h2>
<h2 [class]="{text-danger: true}">标题</h2>
<h2 [ngClass]="{'text-danger': true}">标题</h2>
<h2 [class]="['aa','bb']">标题</h2>
<h2 [class]="arrClass">标题</h2>
public styleStr:string = “background-colo:red;font-size:20px”;
public highlightColor:string = "orange";
public heightStr:string ="200px"
public heightNum:number = 200;
public titleStyles:Object = {
color: "blue",
fontStyle: "italic"
}
<h2 [style] = "styleStr">标题</h2> //绑定值是字符串
<h2 [ngStyle] = "styleStr">标题</h2>
<h2 [style.height] = "heightStr">标题</h2>
<h2 [style.height.px] = "heightNum">标题</h2>
<h2 [style.color] = "hasError ? 'red':'green'">标题</h2>
<h2 [style] = "titleStyles"> </h2>
arr:string[] = ['张三','李四','王五'];
trackByItems(index: number, item: Item): number { return item.id; }
<div *ngFor="let item of arr; let i=index" (click)='choseThis(item,i)'>
索引值:{{i}} -- 内容:{{item}}
</div>
<div *ngFor="let item of items; trackBy: trackByItems">
({{item.id}}) {{item.name}}
</div>
isShow: Boolean = true;
personState: number = 2;
<p *ngIf="isShow">命令模式</p>
<p [style.display]="isShow?'block':'none'">style模式</p>
<p [class.hidden]="isShow">class模式</p>
<div [ngSwitch] = 'personState'>
<div *ngSwitchCase="1">工作</div>
<div *ngSwitchCase="2">吃饭</div>
<div *ngSwitchDefault>睡觉</div>
</div>
eventFunc(e){
console.log(e);
}
<button (click) = "eventFunc($event)">Greet</button> //推荐
<button on-click = "eventFunc($event)">Greet</button>
<input (blur)="eventFunc($event)"> //失去焦点事件
<input (keyup)="eventFunc($event)"> //监听键盘输入事件
<input (keyup.enter)="eventFunc($event)"> //监听键盘输入回车触发事件
//双向数据绑定 [(ngModel)]
//Angular不能直接识别ngModel,需要通过引入模块FormsModule来访问
import {FormsModule} from '@angular/forms';
imports: [FormsModule]
public name = "张三";
<input [(ngModel)] = "name" type="text"> //推荐
<input bindon-change="name" type="text"> //备选
//属性绑定+事件绑定 = ngModel
<input [value]="name" (input)="name=$event.target.value" >
//模板引用变量 #标识(通常是对模板中DOM元素的引用,可以直接通过标识获取dom元素值)
<input #phone placeholder="phone number" /> //推荐
<input ref-phone placeholder="phone number"/> //可以用'ref-'代替'#'
<button (click)="callPhone(phone.value)">Call</button>
指令(属性型指令和结构型指令)
ng generate directive highlight
import { Directive, ElementRef } from '@angular/core';
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective {
constructor(el: ElementRef) {
el.nativeElement.style.backgroundColor = 'yellow';
}
}
<p appHighlight>Highlight me!</p>
import { Directive, ElementRef, HostListener, Input } from '@angular/core';
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective {
@Input('appHighlight') highlightColor: string;
constructor(private el: ElementRef) { }
@HostListener('mouseenter') onMouseEnter() {
this.highlight(this.highlightColor || 'yellow');
}
@HostListener('mouseleave') onMouseLeave() {
this.highlight(null);
}
private highlight(color: string) {
this.el.nativeElement.style.backgroundColor = color;
}
this.el.nativeElement.addEventListener(click,() => {
this.el.nativeElement.style.height = 100px;
})
}
<p [appHighlight]="'red'">Highlight me!</p>
*ngFor *ngIf ngSwitch
import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';
@Directive({ selector: '[ngElse]'})
export class UnlessDirective {
private hasView = false;
constructor(
private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef) { }
@Input() set ngElse(condition: boolean) {
if (!condition && !this.hasView) {
this.viewContainer.createEmbeddedView(this.templateRef);
this.hasView = true;
} else if (condition && this.hasView) {
this.viewContainer.clear();
this.hasView = false;
}
}
}
<p *ngIf="isShow">IF</p>
<p *ngElse="!isShow">ELSE</p>
路由系统
Routes:Array<json>
[{path: '',component : HomeComponent},
{path: 'detail/:id',component : DetailComponent},
{path:'**',component:Page404Component}]
routes=[
{path:'',component:center},
{path:'auxVivwe',component:auxViwe,outlet:'aux'}
]
<router-outlet></router-outlet>
<router-outlet></router-oulet name='aux'>
<a [routerLink]="['/',{outlet:'aux','auxVivwe'}]">1</a>
Router
Router.navigate(Array<string>)
<a router-link="home"></a>
<a [routerLink]="['home']"></a>
ActivatedRouter
proto.queryParams[id]
proto.params[id]
proto.data[index].id
{path:'', redirectTo:'/home',pathMatch:'full'}
CanActivate:fun
CanDeactivate:fun
Resolve:fun
{path:'/home',component:a,CanActivate:[实例,]}
object.subscribe(backFuntion)
object.snapshot.object
依赖注入,控制反转
providers:[{provider:'prod',useClass:prod}]
providers:[{provider:'prod',useFactory:()=>{ return 1},deps:[loge]}]
providers:[{provider:'prod',useValue:false}]
constructor(prod:prod){}
管道(过滤器)
<div>{{value| myDate | json }}</div>
<div>The hero's birthday is {{ birthday | date:"MM/dd/yy" }} </div>
<div>T价格: {{ money | toMoney:'元'}} </div>
json
date:'yyyy-mm-dd'
uppercase
lowercase
number:'2.2-2'
ng g pipe /piper/mypiper
安全导航运算符(很实用)
//可以对在属性路径中出现 null 和 undefined 值进行保护,防止渲染失败
//所以在使用对象的属性的时候,良好的习惯是使用安全导航运算符
//多层嵌套的对象,应该这样使用a?.b?.c?.d
<p>产品: {{product?.name}}</p>
<p>产品: {{product?.name?.firstName}}</p>
通信
@Input() a:string;
@Input()
set b(b: string) {
this._b = (b && b.trim()) || '<no name set>';
}
get b(): string { return this._b; }
@Input() c: function;
func(){ console.log("我是父组件的方法") }
<my-component [a]='helloA' [b]='helloB' [c]="func"></my-component>
<input type="button" (click)="vote(true)">
exprot class son{
//通过EventEmitter实现自定义事件
@Output() voted = new EventEmitter<boolean>();
vote(agreed: boolean) {
this.voted.emit(agreed); //发射
}
}
//父组件,监听自定义事件
<div>
<app-son (voted)="onVoted($event)"> </app-son>
</div>
exprot class app{
agreed = 0;
onVoted(agreed: boolean) {
agreed ? this.agreed++ : agreed--;
}
}
//父组件主动获取子组件的数据或方法 viewChild
<childCompontent #child> </childComponent>
@ViewChild('child') child1:component
this.child1.属性或方法
//非父子组件之间通过服务来通讯,也可以用Localstorage/SessionStorage(h5新增的本地缓存技术)
组件生命周期钩子
钩子 | 时机及用途 |
---|
ngOnChanges() | 时机:当被绑定的输入属性的值发生变化时调用,首次调用一定会发生在 ngOnInit() 之前。用途:当 Angular 设置或重新设置数据绑定的输入属性时响应。 该方法接受当前和上一属性值的 SimpleChanges 对象注意:这发生的非常频繁,所以你在这里执行的任何操作都会显著影响性能。 |
ngOnInit() | 时机:在第一轮 ngOnChanges() 完成之后调用,只调用一次。用途:在 Angular 第一次显示数据绑定和设置指令/组件的输入属性之后,初始化指令/组件。组件获取初始数据的好地方 |
ngDoCheck() | 时机:紧跟在每次执行变更检测时的 ngOnChanges() 和 首次执行变更检测时的 ngOnInit() 后调用。用途:检测,并在发生 Angular 无法或不愿意自己检测的变化时作出反应。注意:它和ngOnChanges一样发生的很频繁 |
ngAfterContentInit() | 时机:第一次 ngDoCheck() 之后调用,只调用一次。用途:当 Angular 把外部内容投影进组件视图或指令所在的视图之后调用 |
ngAfterContentChecked() | 时机:ngAfterContentInit() 和每次 ngDoCheck() 之后调用。用途:每当 Angular 检查完被投影到组件或指令中的内容之后调用。 |
ngAfterViewInit() | 时机:第一次 ngAfterContentChecked() 之后调用,只调用一次。用途:初始化完组件视图及其子视图之后调用。 |
ngAfterViewChecked() | 时机:ngAfterViewInit() 和每次 ngAfterContentChecked() 之后调用。用途:每次做完组件视图和子视图的变更检测之后调用。 |
ngOnDestroy() | 时机:在 Angular 销毁指令/组件之前调用。用途:当 Angular 每次销毁指令/组件之前调用并清扫。 在这儿反订阅可观察对象和分离事件处理器,以防内存泄漏。取消订阅可观察对象;清除定时器;反注册该指令在全局或应用服务中注册过的所有回调。 |
表单处理ngFrom
FormControl 实例用于追踪单个表单控件的值和验证状态。
FormGroup 用于追踪一个表单控件组的值和状态
FormArray 用于追踪表单控件数组的值和状态。
ControlValueAccessor 用于在 Angular 的 FormControl 实例和原生 DOM 元素之间创建一个桥梁。
imports: [ ReactiveFormsModule ]
import { FormControl } from '@angular/forms';
export class FavoriteColorComponent {
name = new FormControl('');
}
<label>Name:
<input type="text" [formControl]="name">
</label>
this.name.setValue('张三');
import { FormGroup, FormControl } from '@angular/forms';
profileForm = new FormGroup({
firstName: new FormControl(''),
lastName: new FormControl(''),
});
<form [formGroup]="profileForm">
<label>
First Name:
<input type="text" formControlName="firstName">
</label>
<label>
Last Name:
<input type="text" formControlName="lastName">
</label>
</form>
//嵌套表单和上面差不多
//也使用 patchValue() 方法用对象中所定义的任何属性为表单模型进行替换。(局部刷新)
this.profileForm.patchValue({
firstName: 'Nancy',
address: {
street: '123 Drew Street'
}
});
//建立模板驱动表单,手动双向绑定
import { Component } from '@angular/core';
@Component({
selector: 'app-template-favorite-color',
template: `color: <input type="text" [(ngModel)]="favoriteColor">`
})
export class FavoriteColorComponent {
favoriteColor = '';
}
//使用 FormBuilder服务生成控件
//第一步:导入 FormBuilder 类。
import { FormBuilder } from '@angular/forms';
//第二步:注入这个 FormBuilder 服务。
constructor(private fb: FormBuilder) { }
//第三步:生成表单内容。
export class ProfileEditorComponent {
//每个控件名对应的值都是一个数组,这个数组中的第一项是其初始值。第二项同步校验,第三项是异步校验
profileForm = this.fb.group({
firstName: ['',,Validators.required],,
lastName: [''],
address: this.fb.group({
street: [''],
city: [''],
state: [''],
zip: ['']
}),
});
}
通过http访问服务器
import { HttpClientModule } from '@angular/common/http';
imports: [HttpClientModule]
import { HttpClient } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError, retry } from 'rxjs/operators';
constructor(private http: HttpClient) { }
getData() {
return this.http.get('请求地址');
}
options: {
headers?: HttpHeaders | {[header: string]: string | string[]},
observe?: 'body' | 'events' | 'response',
params?: HttpParams|{[param: string]: string | string[]},
reportProgress?: boolean,
responseType?: 'arraybuffer'|'blob'|'json'|'text',
withCredentials?: boolean,
}
import { Observable } from 'rxjs/rx';
import { of } from 'rxjs/observable/of';
getHeroes(): Observable<Hero[]> {
this.messageService.add('HeroService: fetched heroes');
return of(HEROES);
}
this.heroService.getHeroes()
.subscribe(heroes => this.refreshTree(heroes));
private checkRequestUrl(requestUrl: string): boolean {
if (!requestUrl || '' == requestUrl.trim() || null == requestUrl) {
console.error('请求url为空,请检查');
return false;
}
return true;
}
private checkParams(data: any): boolean {
if (!postData || null == postData) {
console.error('请求数据为空,请检查');
return false;
}
return true;
}
private planform: PlatformLocation,
private location: Location,
this.profileMenu['href'] = '/profile/setting';
const refreshUrl = this.planform.pathname.split('/', 2)[1];
this.displayChange = refreshUrl === 'page-index';
启动angular
npm start
ng serve --open //启动项目并打开浏览器
ng serve -o //上一句命令的缩写
ng serve --port //指定程序运行端口