[Angular 2] Directive intro and exportAs
First, What is directive, what is the difference between component and directive.
For my understanding,
- component is something like 'canvas', 'form', 'table'... they have the template and their own functionality. It defines how a html tag should work like and look like.
- directive is something like 'ngIf', 'required', 'checked'... they don't necessary to have their own template (of course they can have). It change the original component way to work or looks like.
Basic 'directive' and 'component' they are quite similar, so just follow the rules when you want to choose using 'directive' or 'component':
- Add something new to the DOM with its own template, using component
- Modify something (can be functionality or template) already in teh DOM, using directive.
What we want to build is collapse directive:


When you double click the panel, it will toggle the content show / hide and change the icon.
Also when you click the button which outside the panel, you will also be able to toggle the panel.
So it requires you know
- How to deal with Host elm's events --> @HostListener
- How to deal with Host elm's attrs --> @HostBinding
- How to export directive as API for the component which stay outside the host elm to use --> exportAs
First. let's see how to toggle it by using @HostListener & @HostBinding:
the host element html:
<div collapse-on-click
class="card card-strong disable-text-selection">
<i class="md-icon collapsible-indicator" >arrow_drop_down</i>
<i class="md-icon collapsible-indicator" >arrow_drop_up</i> <div class="collapsible-section" >
This page section is collapsible, double click it and it will collapse or expand.
</div>
</div>
css:
.collapsed .collapsible-section{
display: none;
}
directive:
import {Directive, HostListener, HostBinding} from "@angular/core";
@Directive({
selector: '[collapse-on-click]'
})
export class CollapseOnClick {
collapsed:boolean;
constructor(){
this.collapsed = false;
}
// set "collapsed" class to the host element according to
// this.collapsed value
@HostBinding('class.collapsed')
get isCollapsed(){
return this.collapsed;
}
// if the double click the host element, will fire toggle function
@HostListener('dblclick')
toggle(){
this.collapsed = !this.collapsed;
}
}
So everytime, when you double click the host element, it will run 'toggle()' function, it will change 'this.collapsed' value to true or false. Then we have a getter and setter to get and set 'this.collapsed'. According to 'this.collapsed', we will add 'collapsed' class to host element. This class will help to hide the content, as we define in css file.
So when toggle: true: the host html will change to:
<div collapse-on-click
class="card card-strong disable-text-selection collasped">
When toggle: false:
<div collapse-on-click
class="card card-strong disable-text-selection">
To switch the icon, we can use template reference from directive:
@Directive({
selector: '[collapse-on-click]',
exportAs: 'collapsible'
})
We define exportAs, which we can refer in host html:
<div collapse-on-click #panel="collapsible"
class="card card-strong disable-text-selection">
<i class="md-icon collapsible-indicator" *ngIf="!panel.collapsed">arrow_drop_down</i>
<i class="md-icon collapsible-indicator" *ngIf="panel.collapsed">arrow_drop_up</i> <div class="collapsible-section" >
This page section is collapsible, double click it and it will collapse or expand.
</div>
</div>
And one improvement for using template reference is we not longer need to depend on a css class 'collapsed', to show / hide the content, we can just use ngIf.
<div collapse-on-click #panel="collapsible"
class="card card-strong disable-text-selection">
<i class="md-icon collapsible-indicator" *ngIf="!panel.collapsed">arrow_drop_down</i>
<i class="md-icon collapsible-indicator" *ngIf="panel.collapsed">arrow_drop_up</i> <div class="collapsible-section" *ngIf="!panel.collapsed">
This page section is collapsible, double click it and it will collapse or expand.
</div>
</div>
This way can make the direcitve more reuseable.
Another benifite for using tempalte reference is that, we can call directive function or access directive props by ref.
<div collapse-on-click #panel="collapsible"
class="card card-strong disable-text-selection">
<i class="md-icon collapsible-indicator" *ngIf="!panel.collapsed">arrow_drop_down</i>
<i class="md-icon collapsible-indicator" *ngIf="panel.collapsed">arrow_drop_up</i> <div class="collapsible-section" *ngIf="!panel.collapsed">
This page section is collapsible, double click it and it will collapse or expand.
</div>
</div>
<hr />
<button (click)="panel.toggle()">Toggle: {{panel.collapsed}}</button>
So, we add a button, which stay outside the host element. When it clicked, it will also call the toggle() method on directive to show / hide the content.
Notice: another way to write @HostListener:
@Directive({
selector: '[collapse-on-click]',
exportAs: 'collapsible',
host: {
'(dblclick)': 'toggle()'
}
})
It is also clear.
------------------
app.ts:
import {Component} from "@angular/core";
import {NgModule} from "@angular/core";
import {platformBrowserDynamic} from "@angular/platform-browser-dynamic";
import {BrowserModule} from "@angular/platform-browser";
import {CollapseOnClick} from "./collapse-on-click.directive";
@Component({
selector:'app',
template: `
<div collapse-on-click #panel="collapsible"
class="card card-strong disable-text-selection">
<i class="md-icon collapsible-indicator" *ngIf="!panel.collapsed">arrow_drop_down</i>
<i class="md-icon collapsible-indicator" *ngIf="panel.collapsed">arrow_drop_up</i>
<div class="collapsible-section" *ngIf="!panel.collapsed">
This page section is collapsible, double click it and it will collapse or expand.
</div>
</div>
<hr />
<button (click)="panel.toggle()">Toggle: {{panel.collapsed}}</button>
`
})
export class App {
}
@NgModule({
declarations: [App, CollapseOnClick],
imports: [BrowserModule],
bootstrap: [App]
})
export class AppModule {
}
platformBrowserDynamic().bootstrapModule(AppModule);
collapsed-on-click.ts:
import {Directive, HostListener, HostBinding} from "@angular/core";
@Directive({
selector: '[collapse-on-click]',
exportAs: 'collapsible'
})
export class CollapseOnClick {
collapsed:boolean;
constructor(){
this.collapsed = false;
}
// set "collapsed" class to the host element according to
// this.collapsed value
/*@HostBinding('class.collapsed')
get isCollapsed(){
return this.collapsed;
}*/
// if the double click the host element, will fire toggle function
@HostListener('dblclick')
toggle(){
this.collapsed = !this.collapsed;
}
}
[Angular 2] Directive intro and exportAs的更多相关文章
- [Angular] Export directive functionalities by using 'exportAs'
Directive ables to change component behaives and lookings. Directive can also export some APIs which ...
- 关于angular 自定义directive
关于angular 自定义directive的小结 首先我们创建一个名为"expander"的自定义directive指令: angular.module("myApp& ...
- [Angular] Custom directive Form validator
Create a directive to check no special characters allowed: import {Directive, forwardRef} from '@ang ...
- [Angular] Test Directive
directive: import { Directive, HostListener, HostBinding, ElementRef } from '@angular/core'; @Direct ...
- [Angular] Using directive to create a simple Credit card validator
We will use 'HostListener' and 'HostBinding' to accomplish the task. The HTML: <label> Credit ...
- angular service/directive
<html class=" js cssanimations csstransitions" ng-app="phonecatApp" > < ...
- 一个Demo就懂的Angular之directive
<body> <div ng-controller="myCtrl"> <hello-word></hello-word> < ...
- angular 中 directive中的多个指令
<div ng-controller="ctrl1"> <superman weight length speed>superman</superma ...
- Angular中directive——scope选项与绑定策略,这个也经常迷惑的。
开门见山地说,scope:{}使指令与外界隔离开来,使其模板(template)处于non-inheriting(无继承)的状态,当然除非你在其中使用了transclude嵌入,这点之后的笔记会再详细 ...
随机推荐
- POJ 1160 Post Office
题意:有n个村庄,要在其中m个村庄里建邮局,每个村庄去邮局的代价为当前村庄到最近的一个有邮局村庄的路程,问总最小代价是多少. 解法:dp.dp[i][j]表示在前j个村庄建立i个邮局后的代价,则状态转 ...
- GitHub托管
借助GitHub托管你的项目代码 PS:话说自己注册了GitHub都很久了,却没有怎么去弄,现在系统学习一下,也把自己的学习经历总结下来share给大家,希望大家都能把GitHub用起来,把你的项 ...
- MyGeneration 数据库驱动为空
重做系统后安装了MyGeneration 但是安装完成后发现驱动中没有驱动信息,查了下网上的解决方案发下下面的可以完美解决,特作备忘: The problem is because of multi ...
- 细雨学习笔记:Jmeter测试计划最基本的元素
测试计划-用户组下最基本的元素: 1)HTTP请求默认值 2)HTTP Cookie 管理器(有些操作需要登录后才能访问,用户信息记录在Cookie中,各请求之间就可以共享Cookie了) 3)请求S ...
- EF6 Database First (DbContext) - Change Schema at runtime
Problem:There are two SQL databases (dev and live) with on Azure which has identical table structure ...
- 【windows核心编程】DLL相关(1)
DLL相关的东西 1.DLL的加载方式 隐式: #pragma comment(lib, "XX.lib"); 编译器去查找名为XX.dll的DLL,除了名字相同,该DLL和该LI ...
- ARM指令集----寻址方式
ARM指令集可以分为跳转指令,数据处理指令,程序状态寄存器传输指令,LOAD/Store指令,协处理器指令和异常中断产生指令6类 ARM指令集的寻址方式 数据处理指令的操作数的寻址方式 字以及无符号字 ...
- MFC图形图像
一.CDC类 CDC类简介 CDC类是一个设备上下文类. CDC类提供了用来处理显示器或打印机等设备上下文的成员函数,还有处理与窗口客户区关联的显示上下文的成员函数.使用CDC的成员函数可以进行所有的 ...
- 自定义Camera综述(一般步骤、注意事项、遇到的难题<【内存溢出问题】>、像素参考)
一般步骤: 1. 检查和访问Camera:创建代码来检查Camera和所申请访问的存在性: 2. 创建一个预览类:继承SurfaceView来创建一个Camera的预览类,并实现SurfaceHold ...
- 单词计数WordCountApp.class
public class WordCountApp { // 可以指定目录,目录下如果有二级目录的话,是不会执行的,只会执行一级目录. private static final String INPU ...