[关闭]
@xuemingdeng 2018-08-15T07:35:51.000000Z 字数 5318 阅读 3275

Angular的10个你可能不知道的有用特性

作者:angular-guru.com
译者:李志

摘要:大型框架Angular中隐藏着许多你可能不知道的有趣特性,本文介绍了其中10种。一起来看看吧!

Angular是一个大型框架,大多数人可能都用过其中的一小部分。但在它平凡的外表之下,隐藏着许多有用的特性,可以提高我们的工作效率。本文将介绍Angular的10种你可能没有听说过但却十分有用的特性。

Angular中最容易被忽略却很有用的特性之一就是其提供的各种管道(pipe)。那么我们就先从这里讲起,来看看一些有用的管道吧!

1. 键值管道(KeyValuePipe)

这是Angluar 6.1的主要特性之一。之前的*ngFor指令只允许你迭代数组或可迭代的结构体。如果想要迭代对象中的属性或Map中的项时,就会很麻烦。

这时,KeyValuePipe就能帮我们大忙啦!我们只需将我们想要迭代的对象放到管道里,接下来的事就可以全权交给*ngFor处理了。例如:

  1. @Component({
  2. selector: 'app-list',
  3. template: `
  4. <ul>
  5. <li *ngFor="let word of words | keyvalue">
  6. {{ word.key }}: {{ word.value }}
  7. </li>
  8. </ul>
  9. `
  10. })
  11. export class AppListComponent {
  12. words = new Map([[1, 'Angular'], [2, 'Guru']]);
  13. }

KeyValuePipe的文档详见https://angular.io/api/common/KeyValuePipe

2. 切片管道(Slice Pipe)

渲染一组项目并操作大量DOM节点通常是一个很耗资源的任务,因此有时我们希望减少需要显示的项目的数量。这种操作有许多实现方法,而Angular给出了一个十分简单的解决方案——SlicePipe,可作为ngFor表达式的一部分。

例如,我们想要显示一个数组中的前10项,就可以使用SlicePipe来完成。具体做法如下:

  1. <ul>
  2. <li *ngFor="let item of items | slice:0:10">{{ item }}</li>
  3. </ul>

SlicePipe文档见https://angular.io/api/common/SlicePipe

3. 小数管道(Decimal Pipe)

这是一个十分简单的管道,用于格式化数字,比如控制小数点后显示的数字个数。如果你比较喜欢让自己的数字的显示格式更容易阅读,比如每隔一个千位添加一个逗号(如1000显示为1,000),也可以用这个管道来实现。

与这个管道相关的另一个特性是formatNumber函数,它是@angular/common的一部分,让你可以以编程的方式应用相同的格式,而不是在视图中使用管道。

  1. <p>Your number is: {{ value | number }}</p>

DecimalPipe的文档见https://angular.io/api/common/DecimalPipe

formatNumber的文档见https://angular.io/api/common/formatNumber

4. JSON管道(JSON Pipe)

JSON管道非常有用,尤其是在调试的时候。它可以让你在视图中以字符串的格式显示一个对象。比起在代码中打断点调试,这种方法更为简单易用。

JSON管道的用法很简单,只需要将管道添加到你想要显示的对象后面即可。

  1. <p>{{ myObj | json }}</p>

JsonPipe文档见https://angular.io/api/common/JsonPipe

5. 标题和元服务

该特性在涉及搜索引擎和社交平台(如Google、Twitter、Facebook等)时尤其实用。这些平台会查找你页面上的<meta>标签用于描述页面内容,提供标题、描述、图像等等。

例如,下面这个博客的每篇博文都会有不同的标题、描述和图片。为保证每篇博文获得正确信息,我们可以使用元服务(meta service)。该服务允许我们动态添加和更新页面上的meta标签。具体做法如下:

  1. export class AppComponent {
  2. constructor(meta: Meta) {
  3. // Twitter Markup
  4. this.meta.updateTag({ name: 'twitter:card', content: 'summary_large_image' });
  5. this.meta.updateTag({ name: 'twitter:site', content: '@TheAngularGuru' });
  6. this.meta.updateTag({ name: 'twitter:title', content: 'Article title' });
  7. this.meta.updateTag({ name: 'twitter:description', content: 'Article description' });
  8. this.meta.updateTag({ name: 'twitter:image', content: 'image.jpg' });
  9. }
  10. }

另外,Angular还提供了一个Title服务。也许你已经猜到,该服务的功能是更新浏览器窗口的标题。更新标题的通常做法是为文件头的<title>标签设置一个值,但这样我们就不能使用标准的Angular绑定(如<title>{{ myTitle }}</title>),因为<head>不属于Angular组件。因此,我们必须改用Title服务。该服务的使用方法极其简单:

  1. export class AppComponent {
  2. constructor(title: Title) {
  3. title.setTitle('Window Title here');
  4. }
  5. }

Meta的文档见https://angular.io/api/platform-browser/Meta

Title的文档见https://angular.io/api/platform-browser/Title

6. ng-container

你是否有过这样的经历:想要将两个结构指令放在一个元素里,搞了半天却发现并不能这样做……

或者,你希望使用ngTemplateOutlet插入一个模板,结果发现插入的模板并不是子元素,而是变成了兄弟元素。

这非常糟心。因为你为了实现以上功能,需要添加一个随机的包裹<div>元素。而这种实现方法不仅不理想,还会污染你干净的DOM结构。

幸运的是,我们还有ng-container元素,可以避免上述问题。该元素只在开发过程中出现,实际上并不会在DOM上增加任何新元素,因此可以用来解决包括上述问题在内的很多问题。

例如,两个结构指令的问题可以用以下方式解决:

  1. <ng-container *ngIf="condition">
  2. <div *ngFor="let item of items">{{ item }}</div>
  3. </ng-container>

插入模板作为子元素:

  1. <div>
  2. <ng-container [ngTemplateOutlet]="template"></ng-container>
  3. </div>

上面两个例子只是该元素的诸多用法中的冰山一角。我相信你一定会发掘出它的更多应用!

7. 属性装饰器(Attribute Decorator)

我们都知道,@Input和@Output是用来绑定和释放事件的属性装饰器。其实还有另一种比较小众的装饰器,@Attribute装饰器。

这个装饰器在某些方面和@Input装饰器有点像,因为它可以用于向组件传递值。

这种属性绑定和AngularJS的字面量作用域(literal scope)绑定很像:

  1. scope: {
  2. type: '@'
  3. }

首先我们来看一下这种绑定的不足之处:

尽管有其局限性,如果我们不需要在意以上问题时,该方法还是能为我们提供很多方便,因为这些属性不属于绑定,在变更检测中不需要检查它们。

@Attribute装饰器的使用方法和@Input装饰器相似:

  1. @Attribute() type: string;

Attribute指令的文档见https://angular.io/api/core/Attribute

更多内容还可参见这篇关于Attribute指令的文章:https://netbasal.com/getting-to-know-the-attribute-decorator-in-angular-4f7c9fb61243

8. 分析变更检测

我想大家一定都知道,在所有Angular CLI项目中,main.ts文件都会调用enableProdMode函数。其实,该文件还可以调用enableDebugMode函数。你可能会想,如果代码不在生产模式下运行,一定是在调试模式下运行,但事实并非如此(至少在调用本函数时不是这样的)。

通过调用这个函数,我们在window.ng对象上会获得一个额外的工具,叫做profiler。profiler中有一个函数叫做timeChangeDetection。当这个函数被调用时,会在控制台打印出变更检测的周期和每个周期的运行时间。

当需要分析性能较差的应用时,这个函数尤其有用。要调用这一函数,只需在引导代码中添加如下片段:

  1. platformBrowserDynamic().bootstrapModule(AppModule).then(ref => {
  2. const applicationRef = ref.injector.get(ApplicationRef);
  3. const appComponent = applicationRef.components[0];
  4. enableDebugTools(appComponent);
  5. });

若要开始进行分析,只需在DevTools控制台上运行如下代码:

  1. ng.profiler.timeChangeDetection();

9. NgPlural

在很多应用中,你可能需要描述一系列项目,而此时语言是个很麻烦的问题。比如,我们经常需要处理名词的单复数问题。例如,考虑如下三种情况:

而针对这一情况,ngPlural指令就是一个非常易用的处理方式。上面的例子可以用以下方式处理:

  1. <p [ngPlural]="value">
  2. <ng-template ngPluralCase="=0">There are no items</ng-template>
  3. <ng-template ngPluralCase="=1">There is 1 item</ng-template>
  4. <ng-template ngPluralCase="other">There are {{ value }} items</ng-template>
  5. </p>

NgPlural文档见https://angular.io/api/common/NgPlural

NgPluralCase文档见https://angular.io/api/common/NgPluralCase

10. ngPreserveWhitespaces和NgNonBindable

我把这两条指令放在一起来讲,因为在实际应用中,当需要对内容进行格式化时,这两条指令往往都会被用到。

在Angular 5中,angularCompilerOptions里加入了preserveWhitespaces选项。如果该选项被设置为false,编译器会移除所有不必要的空格。这对代码格式会有一些小小的影响,但却可以帮助我们缩小包的大小。

但是,有时候我们也希望完整地保留空格。如果希望整个组件保留其空格,只需要在组件装饰器中使用如下选项:

  1. @Component({
  2. selector: 'app',
  3. templateUrl: './app.component.html',
  4. preserveWhitespace: true
  5. })

有时,我们可能只需要在某个特定的DOM元素中保留空格。这时,我们可以使用ngPreserveWhitespaces指令,如下所示:

  1. <div ngPreserveWhitespaces>
  2. <!-- All whitespace here will be preserved -->
  3. </div>

另外,我们有时可能需要在文档中使用{{ }},但Angular会把这一符号看作插值,并会计算括号中内容的值。这时,可以将ngNonBindable指令插入父元素中,让Angular忽略其中的括号。示例用法如下:

  1. <span ngNonBindable>{{ this will not be evaluated }}</span>

10个你可能不知道的Angular特性已经介绍完毕,希望这些特性能够给你们带来帮助!

英文原文https://angular-guru.com/blog/angular-unknown-features

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注