[英]Add class to next element in Angular2 Directive
I have a dropdown menu and I wanna use angular2 directive to handling open/close of this dropdown.我有一个下拉菜单,我想使用 angular2 指令来处理这个下拉菜单的打开/关闭。 How can I add
open
class to the latest-notification
div .如何将
open
类添加到latest-notification
div 。 by knowing that my directive applied to the button
tag!通过知道我的指令应用于
button
标签!
Here is my html code:这是我的 html 代码:
<div class="header-notification" (clickOutside)="showPopupNotification = false">
<button appDropdown>
<span [class.has-notification]="hasNotification"></span><icon name="ico_notification"></icon>
</button>
<div class="latest-notification">
<span class="top-pointer"><icon name="arrow-popup"></icon></span>
<div class="wrap">
<ul>
<li *ngFor="let notify of notifications" [class.seen]="notify.seen">
<a>
<avatar src="{{notify.userProfileUrl}}" size="35"></avatar>
<time>{{notify.createAt}}</time>
<h5>{{notify.name}}</h5>
<p>{{notify.message}}</p>
</a>
</li>
</ul>
</div>
</div>
</div>
And here's my directive:这是我的指令:
import {Directive, HostBinding, HostListener} from '@angular/core';
@Directive({
selector: '[appDropdown]'
})
export class DropdownDirective {
private isOpen = false;
@HostBinding('class.open') get opened() {
return this.isOpen;
}
@HostListener('click') open() {
this.isOpen = !this.isOpen;
}
constructor() { }
}
Here is a solution I found.这是我找到的解决方案。 I don't this is a right way or best way.
我不认为这是正确的方法或最好的方法。 but at least it's working.
但至少它起作用了。
Now by added toggle
directive to the button directive will be activated and by click on it a class with name of open
will be added to the next element latest-notification
.现在,通过将
toggle
指令添加到按钮指令将被激活,并且通过单击它,一个名为open
的类将被添加到下一个元素latest-notification
。 and also when click outside of the button the open
class will be removed.并且当在按钮外部单击时,
open
类将被删除。 let me know what your guys thinking .让我知道你们的想法。
HTML side: HTML端:
<div class="header-notification">
<button toggle>
...
</button>
<div class="latest-notification">
...
</div>
</div>
and here is directive :这是指令:
import {Directive, HostListener, ElementRef, Renderer, EventEmitter} from '@angular/core';
@Directive({
selector: '[toggle]'
})
export class DropdownDirective {
isOpen = false;
constructor(private el: ElementRef, private renderer: Renderer) {}
@HostListener('click') open() {
let nextElement = this.el.nativeElement.nextElementSibling;
this.isOpen = !this.isOpen;
if (this.isOpen === true) {
this.renderer.setElementClass(nextElement, "open", true);
} else {
this.renderer.setElementClass(nextElement, "open", false);
}
}
// close dropdown if clicked outside
public clickOutside = new EventEmitter<MouseEvent>();
@HostListener('document:click', ['$event', '$event.target'])
public onClick(event: MouseEvent, targetElement: HTMLElement): void {
if (!targetElement) {
return;
}
const clickedInside = this.el.nativeElement.contains(targetElement);
if (!clickedInside) {
this.clickOutside.emit(event);
this.isOpen = false;
let dropdown = this.el.nativeElement.nextElementSibling;
this.renderer.setElementClass(dropdown,"open", false);
}
}
}
Sorry for late respond.抱歉回复晚了。
You could use exportAs
meta property in directive to achieve what you want.您可以在指令中使用
exportAs
元属性来实现您想要的。
(I'll show you relevant lines only where you need to make changes) (我只会在您需要进行更改的地方向您显示相关行)
/* #temp is a local template variable */
/* mydir is defined in dropdowndirective as exportAs meta property */
<button #temp=mydir appDropdown>
/* using vc which is defined in dropdown component */
<div class="latest-notification" [class.open]="vc.isOpen" [class.close]="!vc.isOpen">
import {DropdownDirective} from 'path';
export class DropDownComponent{
@Viewchild('temp') vc:DropdownDirective; // vc can hold isOpen variable directly defined in Dropdowndirective.
}
@Directive({
selector: '[appDropdown]'
exportAs:'myDir' // addded this line
})
Demo : http://plnkr.co/edit/AE8n4McCez7ioxiTSExL?p=preview演示: http : //plnkr.co/edit/AE8n4McCez7ioxiTSExL?p=preview
Hello i made an improved update to @Sajad answer regarding:您好,我对@Sajad 的回答进行了改进更新:
HTML HTML
<div class="btn-group">
<button type="button" class="btn btn-primary dropdown-toggle"
appDropdown
>
Manage Recipe
</button>
<div class="dropdown-menu">
<a class="dropdown-item" href="#">To Shop List</a>
<a class="dropdown-item" href="#">Edit Recipe</a>
<a class="dropdown-item" href="#">Delete Recipe</a>
</div>
</div>
Directive指示
import {Directive, ElementRef, EventEmitter, HostListener, Renderer2} from '@angular/core';
@Directive({
selector: '[appDropdown]'
})
export class DropdownDirective {
isOpen:boolean = false;
constructor( private elRef: ElementRef, private renderer: Renderer2 ) { }
// TOGGLE dropdownMenu
@HostListener('click') toggleOpen(): void {
const dropdownMenu: HTMLElement = this.elRef.nativeElement.nextSibling;
this.isOpen = !this.isOpen;
if( this.isOpen ) {
this.renderer.addClass(dropdownMenu, 'show');
}
else{
this.renderer.removeClass(dropdownMenu, 'show');
}
console.log(this.isOpen);
}
// CLOSE dropdown if outside click
clickOutside = new EventEmitter<Event>();
@HostListener('document:click', ['$event', '$event.target'])
onClick( event: Event, targetElement: HTMLElement ): void {
if (!targetElement || this.isOpen === false ) return;
const dropdownMenu: HTMLElement = this.elRef.nativeElement.nextSibling;
let clickedInside = this.elRef.nativeElement.contains(targetElement);
if (!clickedInside) {
this.clickOutside.emit(event);
this.renderer.removeClass(dropdownMenu,'show');
this.isOpen = false;
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.