详解Angular2 之 结构型指令


Posted in Javascript onJune 21, 2017

Angular 有一个强力的模板引擎,它能让你轻松维护元素的DOM树结构。

Angular指令可分为三种

  1. 组件
  2. 属性型指令
  3. 结构型指令

组件

组件其实就是一个带模板的指令。是这三种指令中最常用的,我们会编写大量的组件来构建application。

属性型指令

属性型指令会修改元素的外观或者行为。 e.g. NgStyle可以修改元素的好几个样式。

结构型指令

结构型指令通过添加和删除 DOM 元素来改变DOM的布局。

我们经常看到的内置的结构型指令有:ngIf、ngSwitch、ngFor。

下面我们着重介绍ngIf。

NgIf案例分析

该指令接受一个布尔值,并据此让一整块DOM树出现或者消失。

注意:这里是出现或者消失,并不是隐藏。

隐藏元素的利弊

当我们隐藏元素时,组件的行为还在继续。

它仍然附加子啊它所属于的DOM元素上,它仍然在监听事件。angular会继续检查哪些能影响数据绑定的变更。组件原本要做的哪些事情仍然在进行!它还是占用着那么多的资源。

另外一方面,重新显示这个组件会很快。

组件以前的状态被保留着,并随时可以显示。组件不用重新初始化,当然,该操作付出代价比较大!

移除元素组件


把ngIf设置为false,将会影响到组件的资源消耗。angular会从DOM中移除该元素,停止相关组件的变更检测,把它从DOM事件中移除,并且销毁组件。组件会被垃圾回收,并释放内存。


如果我们很快再次使用这个组件的时候,重建组件的代价是非常大的。

当ngIf重新变成true的时候,angular会重新创建该组件及其子树。angular会重新运行每个组件的初始化逻辑。

总结

基于上面的利弊分析,无论是我们在使用内置的指令还是使用自定的指令的时候,我们应该自己分析提添加、移除元素以及创建和销毁组件的后果。

标签

在Angular应用之外,标签的默认CSS属性display是none。 它的内容存在于一个隐藏的文档片段中。
而在Angular应用中,Angular会移除 标签及其子元素。

我们可以通过把短语”Hip! Hip! Hooray!”中间的”hip”包在一个标签中来验证下这个效果。

<p>
 Hip!
</p>
<template>
 <p>
  Hip!
 </p>
</template>
<p>
 Hooray!
</p>

这时候显示的内容是'Hip! Hooray!',在Angular的控制下,DOM的效果是不同的。

详解Angular2 之 结构型指令

显然,Angular把标签及其内容替换成了一个空白

自定义指令

我们自顶一个类似ngIf的指令。

import { Directive, Input } from '@angular/core';
import { TemplateRef, ViewContainerRef } from '@angular/core';

/** 选中器[],是匹配页面上的指令,可以有多个名称,由于是自己的指令,所以没有使用ng开头 */
@Directive({ selector: '[myUnless]' })
export class UnlessDirective {
 /**
  * 我们需要访问模板,并且还需要一个渲染器来渲染它的内容。
  * 我们通过TemplateRef来访问模板。渲染器是ViewContainerRef。
  * 我们把它们都作为私有变量注入到构造函数中。
  */
 constructor(
  private templateRef: TemplateRef<any>,
  private viewContainer: ViewContainerRef
  ) { }

 /**
  * 如果条件为假,我们就渲染模板,否则就清空元素内容。
  * 我们现在先把myUnless属性定义成一个“只写”属性。
  */
 @Input() set myUnless(condition: boolean) {
  if (!condition) {
   this.viewContainer.createEmbeddedView(this.templateRef);
  } else {
   this.viewContainer.clear();
  }
 }
}

几个概念

星号(*)效果

这个星号是一种“语法糖”。它简化了ngIf和ngFor —— 无论是写还是读。

ngIf

接下来这两个ngIf范例的效果完全相同,只是我们写成了另一种风格:

<!-- Examples (A) and (B) are the same -->
<!-- (A) *ngIf paragraph -->
<p *ngIf="condition">
 Our heroes are true!
</p>

<!-- (B) [ngIf] with template -->
<template [ngIf]="condition">
 <p>
  Our heroes are true!
 </p>
</template>

要知道,Angular会把风格(A)写成风格(B)。 它把段落及其内容移到了 标签中。 它把指令移到了 标签上,成为该标签的一个属性绑定 —— 包装在方括号中。 宿主组件的condition 属性的布尔值决定该模板的内容是否应该被显示。

ngFor

Angular把*ngFor转换成一个类似的形式:

<!-- Examples (A) and (B) are the same -->

<!-- (A) *ngFor div -->
<div *ngFor="let hero of heroes">{{ hero }}</div>

<!-- (B) ngFor with template -->
<template ngFor let-hero [ngForOf]="heroes">
 <div>{{ hero }}</div>
</template>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
利用jquery.qrcode在页面上生成二维码且支持中文
Feb 12 Javascript
简介JavaScript中fixed()方法的使用
Jun 08 Javascript
Javascript实现前端简单的路由实例
Sep 11 Javascript
利用js来实现缩略语列表、文献来源链接和快捷键列表
Dec 16 Javascript
JavaScript-定时器0~9抽奖系统详解(代码)
Aug 16 Javascript
详解Webpack+Babel+React开发环境的搭建的方法步骤
Jan 09 Javascript
详解项目升级到vue-cli3的正确姿势
Jan 28 Javascript
详解关于微信setData回调函数中的坑
Feb 18 Javascript
详解vue-cli+element-ui树形表格(多级表格折腾小计)
Apr 17 Javascript
微信小程序实现跳转的几种方式总结(推荐)
Apr 24 Javascript
微信小程序 行的删除和增加操作实现详解
Sep 29 Javascript
绘制微信小程序验证码功能的实例代码
Jan 05 Javascript
JavaScript用200行代码制作打飞机小游戏实例
Jun 21 #Javascript
Angular.JS中指令ng-if的注意事项小结
Jun 21 #Javascript
jquery.validate表单验证插件使用详解
Jun 21 #jQuery
JS实现简单拖拽效果
Jun 21 #Javascript
详解Vue路由开启keep-alive时的注意点
Jun 20 #Javascript
jquery基于layui实现二级联动下拉选择(省份城市选择)
Jun 20 #jQuery
详解Node.js access_token的获取、存储及更新
Jun 20 #Javascript
You might like
php at(@)符号的用法简介
2009/07/11 PHP
PHP 使用MySQL管理Session的回调函数详解
2013/06/21 PHP
php上传文件中文文件名乱码的解决方法
2013/11/01 PHP
golang与php实现计算两个经纬度之间距离的方法
2016/07/22 PHP
Laravel最佳分割路由文件(routes.php)的方式
2016/08/04 PHP
php rmdir使用递归函数删除非空目录实例详解
2016/10/20 PHP
PHP7如何开启Opcode打造强悍性能详解
2018/05/11 PHP
js cookies 常见网页木马挂马代码 24小时只加载一次
2009/04/13 Javascript
JavaScript 比较时间大小的代码
2010/04/24 Javascript
jquery 如何动态添加、删除class样式方法介绍
2012/11/07 Javascript
运算符&amp;&amp;的三个不同层次
2013/04/07 Javascript
jquery、js操作checkbox全选反选
2014/03/12 Javascript
禁用Enter键表单自动提交实现代码
2014/05/22 Javascript
JavaScript中Number.NEGATIVE_INFINITY值的使用详解
2015/06/05 Javascript
JavaScript的RequireJS库入门指南
2015/07/01 Javascript
jQuery中iframe的操作(点击按钮新增窗口)
2016/04/20 Javascript
JavaScript对象_动力节点Java学院整理
2017/06/23 Javascript
JS实现盒子跟着鼠标移动及键盘方向键控制盒子移动效果示例
2019/01/29 Javascript
详解微信小程序支付流程与梳理
2019/07/16 Javascript
微信小程序使用npm包的方法步骤
2019/08/13 Javascript
[01:04:14]VP vs TNC 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/20 DOTA
Python实现图片转字符画的示例
2017/08/22 Python
python实现机械分词之逆向最大匹配算法代码示例
2017/12/13 Python
Python设计模式之简单工厂模式实例详解
2019/01/22 Python
PyQt5下拉式复选框QComboCheckBox的实例
2019/06/25 Python
Django上线部署之IIS的配置方法
2019/08/22 Python
Python函数必须先定义,后调用说明(函数调用函数例外)
2020/06/02 Python
暇步士官网:Hush Puppies
2016/09/22 全球购物
师范学院美术系毕业生自我鉴定
2014/01/29 职场文书
革命先烈的英雄事迹材料
2014/02/15 职场文书
技术总监管理职责范本
2014/03/06 职场文书
灰雀教学反思
2014/04/28 职场文书
食品安全汇报材料
2014/08/18 职场文书
简短清晨问候语
2015/11/10 职场文书
MySQL时间设置注意事项的深入总结
2021/05/06 MySQL
JS setTimeout与setInterval的区别
2022/04/20 Javascript