angular11源码探索五[管道源码篇]

ngNonBindable

原样输出

<span ngNonBindable>{{text}}</span>

Location

Angular Location 服务用于与浏览器URL进行交互,使用他来读取当前URL,修改或者前进或者后退

Angular Router 导航到应用程序的不同的位置,Location不执行导航,但允许我们操作URL,他完全绕过了Angular Router

通常我们用它来返回上一个历史记录

location.back()

或者获取当前路径

this.location.path()

最好使用路由器服务来触发路由更改。仅在需要操纵路由器而不会导致页面刷新时才使用定位服务。

asyncPipe

<h1>{{num|async}}</h1>
<h1>{{promise1|async}}</h1>

  num: Observable<number>= interval(1000)
  promise1=Promise.resolve('成功')

不需要写取消订阅,源码中实现了

  ngOnDestroy(): void {
    if (this._subscription) {
      this._dispose();
    }
  }

 private _dispose(): void {
    this._strategy.dispose(this._subscription!);
    this._latestValue = null;
    this._subscription = null;
    this._obj = null;
  }
   dispose(subscription: Unsubscribable): void {
    subscription.unsubscribe();
  }

  onDestroy(subscription: Unsubscribable): void {
    subscription.unsubscribe();
  }

lowercase

直接上源码

@Pipe({name: 'lowercase'})
export class LowerCasePipe implements PipeTransform {
  /**
   * @param value The string to transform to lower case.
   */
  transform(value: string): string;
  transform(value: null|undefined): null;
  transform(value: string|null|undefined): string|null;
  transform(value: string|null|undefined): string|null {
    if (value == null) return null;
    if (typeof value !== 'string') {
      throw invalidPipeArgumentError(LowerCasePipe, value);
    }
    return value.toLowerCase();
  }
}

比较简单,这个就不多介绍了,输入undefined/null 都返回的null

titlecase

    return value.replace(
        unicodeWordMatch, (txt => txt[0].toUpperCase() + txt.substr(1).toLowerCase()));
  }

uppercase

 transform(value: string|null|undefined): string|null {
    if (value == null) return null;
    if (typeof value !== 'string') {
      throw invalidPipeArgumentError(UpperCasePipe, value);
    }
    return value.toUpperCase();
  }

datePipe

<h1>{{str|date:'yyyy-MM-dd h:mm:ss SSS'}}</h1>

JsonPipe

@Pipe({name: 'json', pure: false})
export class JsonPipe implements PipeTransform {
  /**
   * @param value A value of any type to convert into a JSON-format string.
   */
  transform(value: any): string {
    return JSON.stringify(value, null, 2);
  }
}

keyvaluePipe

  arr = new Map([[1, 2], [3, 4]]);
  obj = {};
  obj1 = {a: 1, b: 2};
  map = new Map();
  map1 = new Map([[1, 2]])

<h1>{{arr|keyvalue|json}}</h1>
// [ { "key": 1, "value": 2 }, { "key": 3, "value": 4 } ]
<h1>{{obj|keyvalue|json}}</h1>
// []
<h1>{{obj1|keyvalue|json}}</h1>
// [ { "key": "a", "value": 1 }, { "key": "b", "value": 2 } ]
<h1>{{map|keyvalue|json}}</h1>
// []
<h1>{{map1|keyvalue|json}}</h1>
// [ { "key": 1, "value": 2 } ]
<div *ngFor="let item of (obj1|keyvalue)">
  {{item.key}}
</div>
// a
// b

<div>{{arr|keyvalue:arrFn}}</div>

  arrFn(a, b) {
    console.log(a, b);
    return a-b;
  }

源码探索

 compareFn: (a: KeyValue<K, V>, b: KeyValue<K, V>) => number = defaultComparator):
      Array<KeyValue<K, V>>|null {
    if (!input || (!(input instanceof Map) && typeof input !== 'object')) {
      return null;
    }
支持的类型主要是 object   Map
第二个参数 compareFn 用于排序
执行的是 defaultComparator
用于的 KeyValueDiffers 来检测key,value的差异性

  if (differChanges) {
      this.keyValues = [];
      differChanges.forEachItem((r: KeyValueChangeRecord<K, V>) => {
        this.keyValues.push(makeKeyValuePair(r.key, r.currentValue!));
      });
      this.keyValues.sort(compareFn);
    }
   默认的情况是对key进行升序排序,可以查看 defaultComparator 函数      

DecimalPipe number管道

{{1241144|number}}
// 默认千分  1,241,144
<h1>{{123|number:'.2'}}</h1>
// 保留两位小数
'1.2-2'
* 小数点前至少显示1位位数,默认设置为1
* 小数点后至少显示2位位数
* 小数点后显示的最大整数位数

百分比
 let num=new PercentPipe('en-US')
    console.log(num.transform(1.23)); // 123%

num.transform(12.34323256,'0.0-2') //保留两位小数

slicePipe

slicePipe:SlicePipe;
  ngOnInit(): void {
    this.slicePipe=new SlicePipe();
    console.log(this.slicePipe.transform([1, 2, 3, 4], 2));
  }
// [3,4]
  console.log(this.slicePipe.transform('abcdef', 2));
// cdef
  console.log(this.slicePipe.transform('abcdef', -3));
// def

<h1>{{[1,2,3,4]|slice:1:3}}</h1>
2,3

源码部分

    if (value == null) return null;
	// 报错, 如果不是Array或者string
    if (!this.supports(value)) {
      throw invalidPipeArgumentError(SlicePipe, value);
    }

    return value.slice(start, end);
  }

  private supports(obj: any): boolean {
    return typeof obj === 'string' || Array.isArray(obj);
  }


函数头
{{[1,2,3,4]|slice:1:3}}
对应的参数是 value 数组   strat 1    end 3
transform(value: string|null|undefined, start: number, end?: number)
posted @ 2020-12-14 00:04  猫神甜辣酱  阅读(201)  评论(0编辑  收藏  举报