angular7.0使用指南

栏目: JavaScript · 发布时间: 7年前

内容简介:如果安装脚手架报错,强制清理npm缓存后重新安装当你下载好官方案列后,你可能对目录都不太熟悉,不过不用关心表达式中的上下文变量是由 ==
  1. 脚手架安装:npm i -g @angular/cli
  2. 新建项目:ng new my-app

如果安装脚手架报错,强制清理npm缓存后重新安装

组件与模板

当你下载好官方案列后,你可能对目录都不太熟悉,不过不用关心

理解模板表达式上下文

==组建实列==就是模板表达式的上下文对象(Expression context)

表达式中的上下文变量是由 == 模板变量 == 、 == 指令的上下文变量 ==(如果有)和 == 组件的成员变量 == 叠加而成的。 当存在相同的表达式变量优先顺序:模板变量、指令的上下文变量、组件的成员变量

import { Component } from '@angular/core';

//my-app/src/app/app.component.ts
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  private data0:Number = 1121; 
  data1 = '<div>dddddd</div>';
  data2 = {
    aaa:222
  };
  data3(){
  };
  data4 = null;
  data5 = undefined;
  data6 = [1,2,3]
}
复制代码
<div>
  <div>data0 :{{data0}}</div>
  <div>data1 :{{data1}}</div>
  <div>data2 :{{data2}}</div>
  <div>data3 :{{data3}}</div>
  <div>data4 :{{data4}}</div>
  <div>data5 :{{data5}}</div>
  <div>data6 :{{data6}}</div>
  <div>data7 :{{data7}}</div>
</div>

<!-- 
	data0 :1121
	data1 :<div>dddddd</div>
	data2 :[object Object]
	data3 :function () { }
	data4 :
	data5 :
	data6 :1,2,3
	data7 : 
-->
复制代码

理解HTML attribute 与 DOM property

先来看一个列子

//html:<input type="text" value="a">
        var outPutVal = function(inO){
            console.log('getAttribute:',inO.getAttribute('value'));
            console.log('inO.value',inO.value);
        }
        window.onload = function(){
            var inO = document.querySelector('input');
            //<input type="text" value="a"> 初始化value后打印
            outPutVal(inO);
            //getAttribute: a
			//test.html:14 inO.value a
            document.onclick = function(){
                //<input type="text" value="a"> 修改value为aaaaa后打印
                outPutVal(inO);
                	//getAttribute: a
				//test.html:14 inO.value aaaaa
            }
        }

		//1.少量 HTML attribute 和 property 之间有着 1:1 的映射,如 id。
		//2.有些 HTML attribute 没有对应的 property,如 colspan。
		//3.有些 DOM property 没有对应的 attribute,如 textContent。
		//4.大量 HTML attribute 看起来映射到了 property…… 但却不像你想的那样!
复制代码

==angular中模板绑定是通过 property 和事件来工作的,而不是 attribute==

特殊的attribute 绑定

[attr.aria-label]="actionName"
<td [attr.colspan]="1 + 1">
复制代码

指令

属性指令

  1. ngClass
  2. ngStyle
  3. ngModel

结构型指令

  1. ngIf
  2. ngFor
  3. ngSwitch

ng-template *号语法

<div *ngIf="hero" class="name">{{hero.name}}</div>
-----------------------------------
<ng-template [ngIf]="hero">
  <div class="name">{{hero.name}}</div>
</ng-template>
复制代码
<div *ngFor="let hero of heroes; let i=index; let odd=odd; trackBy: trackById" [class.odd]="odd">
  ({{i}}) {{hero.name}}
</div>

<ng-template ngFor let-hero [ngForOf]="heroes" let-i="index" let-odd="odd" [ngForTrackBy]="trackById">
  <div [class.odd]="odd">({{i}}) {{hero.name}}</div>
</ng-template>
复制代码

==ng-template 会将内部包裹的元素变成注释==

ng-container

==ng-template 会无副作用的包裹内部元素==

组件(拥有模板的指令)

ng g c components/A 创建组件
复制代码

组件通信

1.输入属性 @Input()

//a.component.ts
  @Input()
  inAttr:String;


  private _name:String = '';
----------------------------------------------------
  @Input()
  set inAttr2(name:String){
    this._name = name;
  }
  
  get inAttr2():String{
    return this._name;
  }
复制代码

2.输出属性 @Output()

//子组件中
	@Output()
	myEvent:EventEmitter<DataType> = new EventEmitter();
	this.myEvent.emit(Data);

	//父组件中
	(myEvent)="myHandleEvent($event)"
	myHandleEvent(Data:DataType){
	    
	}
复制代码

3.中间人模式(兄弟组件通过公共的父组件传值)

4.父组件获得子组件引用 #child(只可以在组件模板中使用)

5. @ViewChild()父组件类插入子组件 (可以在类中使用)

  1. 被注入的计时器组件只有在 Angular 显示了父组件视图之后才能访问
  2. Angular 的单向数据流规则会阻止在同一个周期内更新父组件视图。应用在显示秒数之前会被迫再等一轮。
  3. 使用 setTimeout() 来等下一轮
@ViewChild(CountdownTimerComponent)
    private timerComponent: CountdownTimerComponent;
	
	ngAfterViewInit() {
    // Redefine `seconds()` to get from the `CountdownTimerComponent.seconds` ...
    // but wait a tick first to avoid one-time devMode
    // unidirectional-data-flow-violation error
    setTimeout(() => this.seconds = () => this.timerComponent.seconds, 0);
  }
复制代码

6.通过服务传递数据

自定义指令

ng g d myDirective/demo
复制代码

1.属性型指令

import { Directive, ElementRef, HostListener, Input } from '@angular/core';

@Directive({
  selector: '[appDemo]'
})
export class DemoDirective {

  constructor(private el:ElementRef) { }
  // 注册事件
  @HostListener('click')
  show(){
    console.log(this.el.nativeElement);
    console.log(this.ss);
  }
  //指令参数,当参数名与指令名相同时,可以直接赋值给指令
  @Input()
  ss:String = 'aaa';
}

复制代码

2.结构型指令

import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';

/**
 * Add the template content to the DOM unless the condition is true.
 */
@Directive({ selector: '[appUnless]'})
export class UnlessDirective {
  //第一次传入true时不执行任何if分支
  private hasView = false;

  constructor(
    private templateRef: TemplateRef<any>,
    private viewContainer: ViewContainerRef) { }

  @Input() set appUnless(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;
    }
  }
}
复制代码

目录结构

依赖注入

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}}]
复制代码

@angular/router路由

<!--index.html中的head标签中加入<base href="/">来告诉路由器该如何合成导航用的 URL-->
<base href="/">
复制代码
//app.module.ts
//导入路由核心模块
import { Routes, RouterModule } from '@angular/router';

const routes: Routes = [
  {path:'**',component:AComponent}
];

@NgModule({
  ...
  imports: [RouterModule.forRoot(routes)]
  ...
})
export class AppModule { }
复制代码

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}

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');
  }
}
复制代码

响应式编程:

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,结束啦
复制代码

生命周期钩子

初始化阶段

//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>
复制代码

表单

// 在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('a@a.com'),
    new FormControl('b@b.com')
]);
复制代码

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}) //一次校验多个字段
    
复制代码

以上所述就是小编给大家介绍的《angular7.0使用指南》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Ruby on Rails社区网站开发

Ruby on Rails社区网站开发

布拉德伯纳 / 柳靖 / 2008-10 / 55.00元

《Ruby on Rails社区网站开发》全面探讨创建完整社区网站的开发过程。首先介绍开发一个内容简单的管理系统,之后逐渐添加新特性,以创建更完整的、使用Ruby on Rails 的Web 2.0 社区网站。还给出了开发和测试中的一些建议和提示,同时指导如何使网站更生动以及维护得更好。《Ruby on Rails社区网站开发》也探讨了如何与Flickr 、Google Maps 等其他平台集成,......一起来看看 《Ruby on Rails社区网站开发》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

SHA 加密
SHA 加密

SHA 加密工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具