[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嵌入,这点之后的笔记会再详细 ...
随机推荐
- cgroup隔离的知识点
tasks中写入的是线程号 cgroup.procs是进程号 ===================CPU隔离===================== 主机CPU核数: cat /proc/cpui ...
- [Irving] Wpf DevexPress GridControl 获取选中行
WPF前台绑定事件代码: <RelayAction TargetControl="{Binding ElementName=GCInstoragePart}" MethodN ...
- 【转载】epoll的使用
select,poll,epoll简介 select select本质上是通过设置或者检查存放fd标志位的数据结构来进行下一步处理.这样所带来的缺点是: 1 单个进程可监视的fd数量被限制 2 需要维 ...
- php 解决微信昵称emoji表情插入MySQL报错
在PHP接受到微信用户昵称入库的时候报错 原因:utf-8 最大3个字节,而emoji占4个字节 解决办法: 1.修改mysql 数据库的字符集,改为utf8mb4,但是前提是MySQL的版本需要5. ...
- Python 实例: 备份文件
都说生命苦短,我用python, 所以这两天我也开始学python了. 昨天搞了下语法,今天搞出来个实例,备份文件.尽管编码相当烂,但是测试了一下,还真能用. 它读取一个任务文件, 根据指定的任务参数 ...
- 怎么使用PHPMailer实现邮件的发送??
来源:http://www.ido321.com/1103.html 发送邮件是常用的功能,LZ今天在项目中也碰到了,特此分享一下. 首先,去下载PHPMailer 1.https://github. ...
- document.getElementsByClassName方法的重写(OVERRIDE)
众所周知,对于IE8以下的浏览器(IE8居然是WIN7预装的)没有document.getElementsByClassName,网上也有很多重写的方法,以下是本人在项目中所使用的方法 documen ...
- mount失败
又一次遇到mount失败,提示文件系统类型错误.选项错误.有坏超级块等.之前是在ubuntu 14.04 lts desktop上挂载windows下共享文件夹遇到的.这次具体的环境如下:CentOS ...
- 那些经常被遗忘的 Java 面试题
静态类和静态方法 如果一个类要被声明为static的,只有一种情况,就是静态内部类. 静态内部类实际上与普通类(即类名必须与文件名一样的顶级类)一样,只是静态内部类在某一类的内部定义了而已,既然是类, ...
- cocos2d-x 3.0 创建工程的模板
将下面的代码拷贝到文本文件中,重命名文件为 cocos3.0创建工程.bat @echo off echo -------------------------create project with p ...