[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嵌入,这点之后的笔记会再详细 ...
随机推荐
- HTTP协议中的长连接和短连接(keep-alive状态)
什么是长连接 HTTP1.1规定了默认保持长连接(HTTP persistent connection ,也有翻译为持久连接),数据传输完成了保持TCP连接不断开(不发RST包.不四次握手),等待在同 ...
- XTUOJ1247 Pair-Pair 预处理+暴力
分析:开个1000*1000的数组,预处理矩阵和,然后分类讨论就好 时间复杂度:O(n) #include <cstdio> #include <iostream> #incl ...
- 用VBS脚本发邮件
需求是这样的:针对账号的管理,如果发现该账号的管理员给账号加了批注,(比如要过期,修改密码,完善资料等),就需要找到这样的账号及其管理的邮件,然后发邮件给他们的管理员同时抄送给账号以达到提醒的目的.那 ...
- 使用libzplay库封装一个音频类
装载请说明原地址,谢谢~~ 前两天我已经封装好一个duilib中使用的webkit内核的浏览器控件和一个基于vlc的用于播放视频的视频控件,这两个控件可以分别用在放酷狗播放器的乐库功能和MV ...
- SQL你必须知道的-增删改查与约束
SQL你必须知道的-增删改查与约束 -- 插入数据 --Insert 语句可以省略表名后的列名,但是不推荐 insert into Class values ('' 高一一班 '', ...
- PHP:PHP5.4连接SQLSERVER
在PHP5.4的环境下要连接SQLSERVER(2005/2008)数据库,需要以下步骤: 1.下载PHP5.4连接SQLSERVER的驱动(两个动态连接库)http://www.microsoft. ...
- 用原生javascript模拟经典FC游戏公路争霸
#用原生javascript模拟经典FC游戏公路争霸 前几天看了园子里面的随笔 [原生javascript开发仿微信打飞机小游戏](http://www.cnblogs.com/Mr-Nobody/p ...
- 第三百零五天 how can I 坚持
今天去E世界拿抽的奖品,白去了 一趟,结果已经被拿过去了,明天还得去另一个地拿,太折腾了,今天走了1万4千多步. 哎,徐斌啊,出去见个面,这个折腾啊,受不了,想干他.开个玩笑. 黄东月,为什么打字莫名 ...
- JAVA中“==”与equals()方法区别
equals 方法是 java.lang.Object 类的方法 有两种用法说明: ()对于字符串变量来说,使用"=="和"equals()"方法比较字符串时, ...
- Spring+Quartz 整合二:调度管理与定时任务分离
新的应用场景:很多时候,我们常常会遇到需要动态的添加或修改任务,而spring中所提供的定时任务组件却只能够通过修改xml中trigger的配置才能控制定时任务的时间以及任务的启用或停止,这在带给我们 ...