angular
ng new router / ng new f/s
angular-router
ng new router –routing 或者自己配置路由:
//app-routing.module.ts
import { Routes, RouterModule } from '@angular/router';
const routes: Routes = [
{path:''},
{path:'**',component:CComponent}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
..................................................................
//app.module.ts
@NgModule({
declarations: [
],
imports: [
BrowserModule,
AppRoutingModule
],
providers: [PermissionGuard,FocusGuard,StockResolve],
bootstrap: [AppComponent]
})
Routes路由配置
//const routes: Routes = [{},{}]包含很多对象的数组
// 对象中的属性:
//1.path "**"表示匹配所有
//2.redirectTo "表示要转走的路径"
//3.pathMatch "full"表示匹配程度
//4.component 表示要显示的组件
//5.data 数据传递
//6.children:[] 子路由
//7.canActivate canActivate:[PermissionGuard]
//8.canDeactivate canDeactivate:[FocusGuard]
//9.outlet 辅助路由
//10.resolve resolve:{Stock:StockResolve}
RouterOutlet
Router可调用navigate与navigateByUrl()
RouterLink
<a [routerLink]="['/path']">routelink</a>
<a [routerLink]="['./path']">routelink</a>
<a [routerLink]="['{outlets:{aux:'aaa'}}']">routelink</a> 辅助路由
http://localhost:4200/a(aux:aaa)
路由数据传递:
//1.
[routerLink] = "['/path',1]"
//http://localhost:4200/path/1
// this.routeInfo.snapshot.queryParams
//2.
[routerLink]="['/b',1]" [queryParams]="{id:3}"
// http://localhost:4200/b/1?id=3
// this.routeInfo.snapshot.params
// 3.
{path:'a',component:AComponent,data:{id:666}}
//this.routeInfo.snapshot.queryParams
//this.routeInfo.snapshot.data
ActivatedRoute 常用:this.routeInfo见上面
守卫路由
1.canActivate
export class PermissionGuard implements CanActivate{
canActivate(){
let hasPemission:boolean = Math.random() < 0.5;
return hasPemission;
}
}
2.canDeactivate
export class FocusGuard implements CanDeactivate<CComponent>{
canDeactivate(component:CComponent){
if(component.isFoucs){
return true;
}else {
return confirm('不关注一下嘛?');
}
}
}
3.resolve 读取数据前
@Injectable()
export class StockResolve implements Resolve<Stock>{
constructor(
private route:Router
){}
resolve(route:ActivatedRouteSnapshot,state:RouterStateSnapshot){
return new Stock(1,'name');
}
}
依赖注入 angular实现控制反转的手段就是依赖注入
依赖注入的好处:依赖注入会让你用一种松耦合的方式去写代码,易于调试
注入器:
//只有加入@injectable()才能注入其他
construct(private productService:ProductService){...};
提供器 作用域与优先级
provider:[ProductService]
provider:[{provide:ProductService,useClass:ProductService}]
provider:[{provide:ProductService,useClass:AnotherProductService}]
provider:[{provide:ProductService,useFactory:(参数A)=>{return ob},deps:[参数A]}]
provider:[{provide:"IS_DEV_ENV",useValue:{isDev:true}}]
ng g service f/s
angular只可以在constract中注入
constructor(public injector:Injector){
this.stockService = injector.get(StockService);
}
##数据绑定
####angular4是单向的
###事件绑定
html
<button (click)="onButtonClick($event)"></button>
javascript
onButtonClick(event:any){
console.log(event)
}
###DOM属性绑定
javascript
onButtonClick(event:any){
console.log(event.target.value);//DOM属性
console.log(event.target.getAttribute('value'));//HTML属性
}
//少量HTML属性和DOM属性是1:1的入id
//有些HTML属性没有对应的DOM属性如colspan
//有些DOM属性没有对应的HTML属性入textContent
//就算名字相同,HTML属性与DOM属性也不是同一样东西
//HTML属性的值不可改变,DOM属性值可以改变
//angular模板绑定是通过DOM属性与事件来工作的
###HTML属性绑定
html
1.基本html属性绑定 <tr [attr.colspan]="tableColspan" >Something</tr>
2.CSS类绑定
<div class="aaa bbb" [class]="someExpress">something</div>
<div [class.special]="isSpecial">something</div>
<div [ngClass]="{{aaa:isA,bbb:isB}}"></div>
3.样式绑定 <button >css一致</button>
###双向数据绑定
html
<input [(ngMoudel)]="name">
{{name}}
下面会具体讲解
##响应式编程:
javascript
import {Observable} from "rxjs";
...
Observable.from([1,2,3,4])
.filter(e => e%2 == 0)
.map(e => e*e)
.subscribe(
e => console.log(e),
err => console.error(err),
() => console.log("结束啦")
)
//4,16,结束啦
####angular响应式编程列子
javascript
//1.在app.module.ts imports中加入ReactiveFormsModule
//在你的组建中:
searchInput:FormControl = new FormControl();
constructor(){
this.searchInput.valueChanges.debounceTime(500).subscribe(stockCode => this.getStockInfo(stockCode))
}
getStockInfo(value:string){
console.log(value)
}
html
<input [formControl]="searchInput"> 每当value改变FormControl发射一个valueChange事件
##管道:
html
{time | date:'yyyy-MM-dd HH:mm:ss'}
好多自己查
###自定义管道
“`javascript
//ng g pipe 管道名
javascript
##组件通讯
###输入属性 @Input()
//s.component.ts
@input()
private keyWord:string
//s.component.html
{{keyWord}}
//f.component.html
中间人模式????
javascript
//qq
生命周期钩子
初始化阶段
//1.constructor
//2.ngOnChanges父组件初始化子组件输入属性时被调用 (不可变对象的改变)
ngOnChanges(changes:SimpleChanges):void{
}
//3.ngOnInit
//4.ngDoCheck 一定要判断一下你想要的变化发生时
//5.ngAfterContentInit
//6.ngAfterContentChecked
//7.ngAfterViewInit
//8.ngAfterViewChecked
变化阶段
//1.ngOnChanges
//2.ngDoCheck
//3.ngAfterContentChecked
//4.ngAfterViewChecked
组件销毁阶段
//1.ngOnDestroy
// 在路由变更时改变
ngAfterViewInit,ngAfterViewChecked
//1.子组件组装好父组件才会组装
//2.组件是在试图组装完毕调用
//3.再此方法中不可以更改视图数据
//s.component.ts
greeting(name:string){
...
}
//f.component.html
<app-child #child1></app-child>
<app-child #child2></app-child>
//f.component.ts
@viewChild("child1")
child1:sCompenent;
this.child1.greeting(...);
ngAfterContentInit,ngAfterContentChecked
投影
1.子组件
<div>
<ng-content></ng-content>
</div>
2.父组件
<SComponent>
.......
</SComponent>
投影
1.子组件
<div>
<ng-content select=".a"></ng-content>
</div>
<div>
<ng-content select=".b"></ng-content>
</div>
2.父组件
<SComponent>
<div class="a"></div>
<div class="b"></div>
</SComponent>
表单
// 在imports中:
// ReactiveFormsModule响应式表单
// FormsModule模板式表单
模板式表单
// 在angular中会自动加上ngForm来处理表单,如果不用angular来处理则加上ngNoForm
//在表单中加上#myForm="ngForm",则可以在页面使用{{myForm.value | json}}去检测表单中有ngModule的value 对象名为name值
//(ngSubmit)="..."
NgForm => FormGroup
ngModel=>
ngModelGroup
<form #myForm="ngForm" action="/regist" (ngSubmit)="createUser(myForm.value)" method="post">
<div>
<input ngModel name="a" type="text" required pattern="[a-zA-Z0-9]+">
</div>
<div>
second:<input ngModel #second="ngModel" name="a" type="text" required pattern="[a-zA-Z0-9]+">
</div>
<div>
<input ngModel name="b" type="text" required pattern="[a-zA-Z0-9]+">
</div>
<div ngModelGroup="tow">
<input ngModel name="a" type="text">
<input ngModel name="b" type="text">
</div>
<button type="submit">提交</button>
</form>
<div>
{{myForm.value | json}}
<br>
second值是:{{second.value}}
</div>
模板式表单校验
指令:
// ng g directive f/s
@Directive({
providers:[{provide:NG_VALIDATORS,useValue:mobileValidator,multi:true}]
})
响应式表单
private nickName = new FormControl('tom');
private passwordInfo = new FormGroup({
password: new FormControl(),
passwordConfirm:new FormControl()
});
private email = new FormArray([
new FormControl('[email protected]'),
new FormControl('[email protected]')
]);
FormControl
FormGroup
FormArray
<form [formGroup]="formModel" action="/regist" (Submit)="createUser()" method="post">
<input formControlName="nikname">
<ul formArrayName="emails">
<li *ngFor="let email of formModel.get('emails').controls;let i = index;">
<input [formControlName]="i">
</li>
</ul>
<button >增加email.....</button>
<input formControlName="emails">
<div formGroupName="passwordInfo">
<input formControlName="password">
<input formControlName="passwordConfirm">
</div>
</form>
private formModel:FormGroup;
private fb:FormBuilder = new FormBuilder();
/*this.formModel = new FormGroup({
nikname:new FormControl(),
emails:new FormArray([
new FormControl()
]),
mobile:new FormControl(),
passwordInfo:new FormGroup({
password:new FormControl(),
passwordConfirm:new FormControl()
})
});*/
this.formModel = this.fb.group({
nikname:[''],
emails:this.fb.array([
['']
]),
mobile:[''],
passwordInfo:this.fb.group({
password:[''],
passwordConfirm:['']
})
});
angular表单 校验器
//自定义校验器
xxx(param:AbstractControl):{[key:string]:any}{
return null;
}
// eg:
moblieValid(moblie:FormControl):any{
..........
// return null;表示成功
// return {...};不成功
}
//预定义校验器
Validators.required ......
nikname:["xxxx",[Validators.required,.....]]
.....................
let niknameValid;boolean = this.formModel.get('nikname').valid;
passwordInfo:this.fb.group({
password:[''],
passwordConfirm:['']
},{validator:this.passwordValidator}) //一次校验多个字段
显示错误信息
<div [hidden]="!formModel.hasError('required','nickname')"></div>