Angular 笔记7(组件与模板——管道)

组件与模板

管道

数据格式化常用的内置管道

  • DatePipe:根据本地环境中的规则格式化日期值。
  • UpperCasePipe:把文本全部转换成大写。
  • LowerCasePipe :把文本全部转换成小写。
  • CurrencyPipe :把数字转换成货币字符串,根据本地环境中的规则进行格式化。
  • DecimalPipe:把数字转换成带小数点的字符串,根据本地环境中的规则进行格式化。
  • PercentPipe :把数字转换成百分比字符串,根据本地环境中的规则进行格式化。

使用管道

<p>The hero's birthday is {{ birthday | date }}</p>

使用参数和管道链来格式化数据

可以用可选参数微调管道的输出。

<p>The hero's amount is {{ amount | currency:'EUR':'Euros '}} </p>

格式化日期

<p>The hero's birthday is {{ birthday | date:"MM/dd/yy" }} </p>

串联管道应用两种格式

The chained hero's birthday is
{{ birthday | date | uppercase}}

The chained hero's birthday is
{{  birthday | date:'fullDate' | uppercase}}

为自定义数据转换创建管道

  1. 把 @Pipe 装饰器应用到这个类上,把这个类标记为一个管道
  2. 把你的管道包含在 app.module.ts 文件的NgModule 元数据的 declarations 字段中,以便它能用于模板。
  3. 注册自定义管道。Angular CLI 的 ng generate pipe 命令会自动注册该管道。(与上面两点不同)
  4. 使用 PipeTransform 接口
import { Component } from '@angular/core';
@Component({
  selector: 'app-power-booster',
  template: `
    <h2>Power Booster</h2>
    <p>Super power boost: {{2 | exponentialStrength: 10}}</p>
  `
})
export class PowerBoosterComponent { }
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({name: 'exponentialStrength'})
export class ExponentialStrengthPipe implements PipeTransform {
  transform(value: number, exponent?: number): number {
    return Math.pow(value, isNaN(exponent) ? 1 : exponent);
  }
}

通过管道中的数据绑定来检测变更

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

@Component({
  selector: 'app-power-boost-calculator',
  template: `
    <h2>Power Boost Calculator</h2>
    <div>Normal power: <input [(ngModel)]="power"></div>
    <div>Boost factor: <input [(ngModel)]="factor"></div>
    <p>
      Super Hero Power: {{power | exponentialStrength: factor}}
    </p>
  `
})
export class PowerBoostCalculatorComponent {
  power = 5;
  factor = 1;
}

在这里插入图片描述

检测原始类型和对象引用的纯变更
New hero:
  <input type="text" #box
          (keyup.enter)="addHero(box.value); box.value=''"
          placeholder="hero name">
  <button (click)="reset()">Reset</button>
  <div *ngFor="let hero of heroes">
    {{hero.name}}
  </div>
export class FlyingHeroesComponent {
  heroes: any[] = [];
  canFly = true;
  constructor() { this.reset(); }

  addHero(name: string) {
    name = name.trim();
    if (!name) { return; }
    let hero = {name, canFly: this.canFly};
    this.heroes.push(hero);
  }

  reset() { this.heroes = HEROES.slice(); }
}

以数组作为输入的纯管道可能无法正常工作。Angular 忽略了被改变的数组元素的原因是对数组的引用没有改变。由于 Angular 认为该数组仍是相同的,所以不会更新其显示。

获得所需行为的方法之一是更改对象引用本身。你可以用一个包含新更改过的元素的新数组替换该数组,然后把这个新数组作为输入传给管道。在上面的例子中,你可以创建一个附加了新英雄的数组,并把它赋值给 heroes。 Angular 检测到了这个数组引用的变化,并执行了该管道。

addHero(name: string) {
  name = name.trim();
  if (!name) { return; }
  let hero = {name, canFly: this.canFly};
  if (this.mutate) {
  // 数组形式
  // Pure pipe won't update display because heroes array reference is unchanged
  // Impure pipe will display
  this.heroes.push(hero);
  } else {
  	// 改变了对象引用地址,可以正确执行
    // Pipe updates display because heroes array is a new object
    this.heroes = this.heroes.concat(hero);
  }
}

为了让你的组件更简单,独立于那些使用管道的 HTML,你可以用一个不纯的管道来检测复合对象(如数组)中的变化。

检测复合对象中的非纯变更

虽然非纯管道很实用,但要小心使用。长时间运行非纯管道可能会大大降低你的应用速度。

在这里插入图片描述

从一个可观察对象中解包数据

  • 使用内置的 AsyncPipe 接受一个可观察对象作为输入,并自动订阅输入。
  • AsyncPipe 是一个非纯管道,可以节省组件中的样板代码,以维护订阅,并在数据到达时持续从该可观察对象中提供值。
import { Component } from '@angular/core';

import { Observable, interval } from 'rxjs';
import { map, take } from 'rxjs/operators';

@Component({
  selector: 'app-hero-message',
  template: `
    <h2>Async Hero Message and AsyncPipe</h2>
    <p>Message: {{ message$ | async }}</p>
    <button (click)="resend()">Resend</button>`,
})
export class HeroAsyncMessageComponent {
  message$: Observable<string>;

  private messages = [
    'You are my hero!',
    'You are the best hero!',
    'Will you be my hero?'
  ];

  constructor() { this.resend(); }

  resend() {
    this.message$ = interval(500).pipe(
      map(i => this.messages[i]),
      take(this.messages.length)
    );
  }
}

缓存 HTTP 请求

你可以使用非纯管道 AsyncPipe 接受一个可观察对象作为输入,并自动订阅输入。你也可以创建一个非纯管道来建立和缓存 HTTP 请求。

为避免出现性能问题,只有当请求的 URL 发生变化时才会调用该服务器(如下例所示),并使用该管道缓存服务器的响应。

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

@Component({
  selector: 'app-hero-list',
  template: `
    <h2>Heroes from JSON File</h2>

    <div *ngFor="let hero of ('assets/heroes.json' | fetch) ">
      {{hero.name}}
    </div>

    <p>Heroes as JSON:
      {{'assets/heroes.json' | fetch | json}}
    </p>`
})
export class HeroListComponent { }
import { HttpClient }          from '@angular/common/http';
import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'fetch',
  pure: false
})
export class FetchJsonPipe implements PipeTransform {
  private cachedData: any = null;
  private cachedUrl = '';

  constructor(private http: HttpClient) { }

  transform(url: string): any {
    if (url !== this.cachedUrl) {
      this.cachedData = null;
      this.cachedUrl = url;
      this.http.get(url).subscribe(result => this.cachedData = result);
    }

    return this.cachedData;
  }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值