欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Angular 2.x学习教程之结构指令详解

程序员文章站 2022-04-28 17:23:19
结构指令是什么? 结构指令通过添加和删除 dom 元素来更改 dom 布局。angular 中两个常见的结构指令是 *ngif 和 *ngfor 。 了解 * 号语...

结构指令是什么

结构指令通过添加和删除 dom 元素来更改 dom 布局。angular 中两个常见的结构指令是 *ngif*ngfor

了解 * 号语法

* 号是语法糖,用于避免使用复杂的语法。我们以 *ngif 指令为例:

Angular 2.x学习教程之结构指令详解

(图片来源:https://netbasal.com/)

  • angular 把 host (宿主元素) 包装在 template 标签里面
  • angular 将 ngif 转换为属性绑定 - [ngif]

创建结构指令

首先,让我们了解如何创建一个结构指令。 接下来我们将要实现一个简单的 ngif 指令。

import { directive, input, templateref, viewcontainerref } from '@angular/core';

@directive({ selector: '[myngif]'})
export class myngifdirective {

 constructor(
 private templateref: templateref<any>,
 private viewcontainer: viewcontainerref) { }

 @input() set myngif(condition: boolean) {
 if (condition) {
  this.viewcontainer.createembeddedview(this.templateref);
 } else {
  this.viewcontainer.clear();
 }
 }
}

我们可以按照以下方式使用我们的指令:

<div *myngif=”condition”></div>

下面我们来解释一下上面的代码。

templateref

如名字所示,templateref 用于表示模板的引用。

Angular 2.x学习教程之结构指令详解

(图片来源:https://netbasal.com/)

viewcontainerref

正如上面介绍的,模板中包含了 dom 元素,但如果要显示模板中定义的元素,我们就需要定义一个插入模板中元素的地方。在 angular 中,这个地方被称作容器,而 viewcontainerref 用于表示容器的引用。那什么元素会作为容器呢?

angular 将使用 comment 元素替换 template 元素,作为视图容器。

我们来看一个具体的示例:

@component({
 selector: 'my-app',
 template: `
 <div>
  <h2 *myngif="condition">hello {{name}}</h2>
  <button (click)="condition = !condition">click</button>
 </div>
 `,
})
export class app {
 name: string;
 condition: boolean = false;
 constructor() {
 this.name = 'angular2'
 }
}

以上代码成功运行后,浏览器的显示内容如下:

Angular 2.x学习教程之结构指令详解

(图片来源:https://netbasal.com/)

viewcontainerref 对象提供了 createembeddedview() 方法,该方法接收 templateref 对象作为参数,并将模板中的内容作为容器 (comment 元素) 的兄弟元素,插入到页面中。

现在,你已经了解如何创建结构指令,接下来让我们看看两个具体的实例。

基于用户角色显示不同的内容

指令定义

@directive({selector: '[ifrole]'})
export class ifroledirective {
 user$ : subscription;
 @input("ifrole") rolename : string;

 constructor(
  private templateref : templateref<any>,
  private viewcontainer : viewcontainerref,
  private authservice : authservice ) {}

 ngoninit() {
 this.user$ = this.authservice.user
  .do(() => this.viewcontainer.clear())
  .filter(user => user.role === this.rolename)
  .subscribe(() => {
  this.viewcontainer.createembeddedview(this.templateref);
  });
 }

 ngondestroy() {
 this.user$.unsubscribe();
 }
}

指令应用

<div *ifrole="'admin'">
 only for admin
</div>

<div *ifrole="'client'">
 only for client
</div>

<div *ifrole="'editor'">
 only for editor
</div>

创建 range 指令

指令定义

import { directive, input, viewcontainerref, templateref } from '@angular/core';

@directive({
 selector: '[range]'
})
export class rangedirective {
 _range: number[];

 @input()
 set range(value: number) {
  this.vcr.clear();
  this._range = this.generaterange(value[0], value[1]);
  this._range.foreach(num => {
   this.vcr.createembeddedview(this.tpl, {
    $implicit: num
   });
  });
 }

 constructor(
  private vcr: viewcontainerref,
  private tpl: templateref<any>) { }

 private generaterange(from: number, to: number): number[] {
  var numbers: number[] = [];
  for (let i = from; i <= to; i++) {
   numbers.push(i);
  }
  return numbers;
 }
}

以上示例中,我们在调用 createembeddedview() 方法时,设置了第二个参数 {$implicit: num}  。angular 为我们提供了 let 模板语法,允许在生成上下文时定义和传递上下文。

这将允许我们引用 *range="[20,30]; let num" 模板中声明的变量。我们使用 $implicit 名称,因为我们不知道用户在使用这个指令时,会使用什么名字。

Angular 2.x学习教程之结构指令详解

(图片来源:https://netbasal.com/)

指令应用

<h1>your age:</h1>
<select>
 <ng-container *range="[18, 80]; let num">
 <option [ngvalue]="num">{{num}}</option>
 </ng-container>
</select>

<h1>year:</h1>
<select>
 <ng-container *range="[1998, 2016]; let num">
 <option [ngvalue]="num">{{num}}</option>
 </ng-container>
</select>

以上代码成功运行后,浏览器的显示内容如下:

Angular 2.x学习教程之结构指令详解

(图片来源:https://netbasal.com/)

总结

以上就是这篇文章的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。