基础介绍 - 18233135268/iOS-develop GitHub Wiki


Table of Contents

表单

  1. 只有把FromModule添加到本应用的imports数组中,这样我们才能使用表单
  2. 把组件添加到ngModule 的imports列表中,这会让我们的应用能使用模版驱动表单的所有特性,包括ngmodul
  3. 把组件添加到ngModule 的declarations列表中,这让组件本模块中随处都可以访问


绑定目标



Property 绑定

元素的 Property

  <img [src] = "heroImageUrl">

组件的 Property

  <hero-detail [hero]="currentHero"></hero-detail>

指令的 Property

 <div [ngClass] = "{selected: isSelected}"></div>


事件绑定

元素的事件

  <button (click)="onSave()">Save</button>

组件的事件

  <hero-detail (deleteRequest)="deleteHero()"><hero-detail>

指令的事件

  <div (myClick)="clicked=$event">click me</div>


双向绑定

事件与 property

  <input [(ngModel)]="heroName">


Attribute 绑定

Attribute 例外情况

  <button [attr.aria-label]="help">help</button>


Class 绑定

class property

  <div [class.special]="isSpecial">Special</div>


Style 绑定

style property

   <button [style.color] = "isSpecial ? 'red':'green'">


使用 EventEmitter 实现自定义事件



  1. 指令使用典型的 Angular EventEmitter 来触发自定义事件,指令创建一个 EventEmitter 实例,并且把它的一个属性暴露出来。指令调用 EventEmitter.emit(payload) 来触发事件,传进去的消息载荷可以是任何东西。父指令通过绑定到这个属性来监听这个事件,并且通过$event 对象来访问这个载荷。
template: `
<div>
  <img src="{{heroImageUrl}}">
  <span [style.text-decoration]="lineThrough">
    {{prefix}} {{hero?.fullName}}
  </span>
  <button (click)="delete()">Delete</button>
</div>`
// This component make a request but it can't actually delete a hero.
deleteRequest = new EventEmitter<Hero>();

delete() {
  this.deleteRequest.emit(this.hero);
}


NgSwitch

<span [ngSwitch]="toeChoice">
  <span *ngSwitchCase="'Eenie'">Eenie</span>
  <span *ngSwitchCase="'Meanie'">Meanie</span>
  <span *ngSwitchCase="'Miney'">Miney</span>
  <span *ngSwitchCase="'Moe'">Moe</span>
  <span *ngSwitchDefault>other</span>
</span>
  1. ngSwitch: 绑定到一个返回开关值的表达式
  2. ngSwitchCase: 绑定到一个返回匹配值的表达式
  3. ngSwitchDefault: 一个用于标记出默认元素的 Attribute


Angular 小抄



// *符号表示当前元素将变成一个内嵌模版 等价于

...

<p *myUnless="myExpression">...</p>	

组件与指令的变更检测与生命周期的钩子


// 构造器,所有生命周期钩子之前调用,使用它来注入依赖,但是要避免用它做较重的工作
 constructor(myService: MyService,...){...}
// 在输入属性每次变化了之后,开始处理内容或子视图之前被调用。
 ngOnChanges(changeRecord){...}
// 在执行构造函数,初始化输入属性,第一次调用完 ngOnChanges 之后调用
 ngOnInit(){...}
// 每当检查组件或指令的输入属性是否变化时调用,通过它,可以用自定义的方式来扩展变更检测逻辑
 ngDoCheck(){...}
// 当组件或指令的内容已经初始化,ngOnInit 完成之后调用
 ngAfterContentInit(){...}
// 在每次检查完组件或指令的内容之后调用
 ngAfterContentChecked(){...}
// 当组件的视图已经初始化完毕,每次 ngAfterContentInit 之后被调用,只适用于组件
 ngAfterViewInit(){...}
// 每次检查完组件的视图之后调用,只适用于组件
 ngAfterViewChecked(){...}
// 在所属实例被销毁之前,只调用一次
ngOnDestroy(){...}


路由



路由参数

  1. 可选信息有很多种形式,搜索条件通常就不是严格结构化的,比如 name="wind";有很多个值也很常见如 after='12/31/2015'&&'1/1/2017';而且顺序无关,如 before='1/1/2017'&after='12/31/2015' ,还可能有很多种变体格式,如 during='currentYear' 。

为路由组件添加动画

// HostBinding 装饰器来绑定到路由组件

import { Component, OnInit, HostBinding,
         trigger, transition, animate,
         style, state } from '@angular/core';
// 转场动画组件进入应用视图时触发 (void=>*), (*=>void) 在离开时触发
@Component({
  template: `
  <h2>HEROES</h2>
  <div *ngIf="hero">
    <h3>"{{hero.name}}"</h3>
    <div>
      <label>Id: </label>{{hero.id}}</div>
    <div>
      <label>Name: </label>
      <input [(ngModel)]="hero.name" placeholder="name"/>
    </div>
    <p>
      <button (click)="gotoHeroes()">Back</button>
    </p>
  </div>
  `,
  animations: [
    trigger('routeAnimation', [
      state('*',
        style({
          opacity: 1,
          transform: 'translateX(0)'
        })
      ),
      transition('void => *', [
        style({
          opacity: 0,
          transform: 'translateX(-100%)'
        }),
        animate('0.2s ease-in')
      ]),
      transition('* => void', [
        animate('0.5s ease-out', style({
          opacity: 0,
          transform: 'translateY(100%)'
        }))
      ])
    ])
  ]
})


路由重定向

import { ModuleWithProviders }   from '@angular/core';
import { Routes, RouterModule }  from '@angular/router';

import { CrisisCenterHomeComponent } from './crisis-center-home.component';
import { CrisisListComponent }       from './crisis-list.component';
import { CrisisCenterComponent }     from './crisis-center.component';
import { CrisisDetailComponent }     from './crisis-detail.component';

const crisisCenterRoutes: Routes = [
  {
    path: ,
    redirectTo: '/crisis-center',
    pathMatch: 'full'
  },
  {
    path: 'crisis-center',
    component: CrisisCenterComponent,
    children: [
      {
        path: ,
        component: CrisisListComponent,
        children: [
          {
            path: ':id',
            component: CrisisDetailComponent,
          },
          {
            path: ,
            component: CrisisCenterHomeComponent
          }
        ]
      }
    ]
  }
];

export const crisisCenterRouting: ModuleWithProviders = RouterModule.forChild(crisisCenterRoutes);


相对导航

  1. 要使用 Route 进行相对导航,可以使用 ActivatedRoute 来告诉路由器我们正在 RouterState 中的什么地方,RouterState 是激活路由组成的树。要做到这一点,我们可以为 router.navigate 方法中链接参数数组后的对象型参数指定 relativeTo 属性。只要把这个 relativeTo 属性设置为我们的 ActivatedRoute ,路由器就会把我们的导航信息和当前的 URL 合并在一起。
  2. 当使用路由器的 navigateByUrl 方法时,导航总是绝对的
// 把 ActivatedRoute 注入到构造函数中
constructor(
  private service: CrisisService,
  private route: ActivatedRoute,
  private router: Router) {}
<source/>
<source lang="html">
onSelect(crisis: Crisis) {
  this.selectedId = crisis.id;

  // Navigate with relative link
  this.router.navigate([crisis.id], { relativeTo: this.route });
}
gotoCrises() {
  let crisisId = this.crisis ? this.crisis.id : null;
  // Pass along the crisis id if available
  // so that the CrisisListComponent can select that crisis.
  // Add a totally useless `foo` parameter for kicks.
  // Relative navigation back to the crises
  this.router.navigate(['../', { id: crisisId, foo: 'foo' }], { relativeTo: this.route });

}




路由守卫

  1. 用 CanActivate 来处理导航到某路由的情况
  2. 用 CanActivateChild 处理导航到子路由的情况
  3. 用 CanDeactivate 来处理从当前路由离开的情况
  4. 用 Resolve 在路由激活之前获取路由数据
  5. 用 CanLoad 来处理异步导航到某特性模块的情况

⚠️ **GitHub.com Fallback** ⚠️