当前位置: 移动技术网 > IT编程>脚本编程>AngularJs > Angular 2.x学习教程之结构指令详解

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

2018年04月26日  | 移动技术网IT编程  | 我要评论

结构指令是什么

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

了解 * 号语法

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

(图片来源: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 用于表示模板的引用。

(图片来源: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'
 }
}

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

(图片来源: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 名称,因为我们不知道用户在使用这个指令时,会使用什么名字。

(图片来源: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>

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

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

总结

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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网