2017-01-24 3 views
1

У меня есть выпадающее меню, и я хочу использовать директиву angular2 для обработки открывания/закрытия этого выпадающего списка. Как добавить класс open в раздел latest-notification. зная, что моя директива применяется к тегу button!Добавить класс в следующий элемент в Angular2 Директива

Вот мой 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> 

А вот моя директива:

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() { } 

} 
+1

@micronyks Конечно. Как я могу это достичь? – Sajad

+0

Итак, вы готовы? – micronyks

+1

@micronyks нет ждать, позвольте мне разогреться !!! – Sajad

ответ

2

Вот решение, которое я нашел. Я не думаю, что это правильный путь или лучший способ. но по крайней мере он работает.

Теперь добавленнием toggle директивы к директиве кнопка будет активирована, и щелкните по нему класс с именем open будет добавлен к следующему элементу latest-notification. а также при нажатии за пределами кнопки класс open будет удален. дайте мне знать, о чем думают ваши парни.

HTML сторона:

<div class="header-notification"> 
    <button toggle> 
    ... 
    </button> 
    <div class="latest-notification"> 
    ... 
    </div> 
</div> 

и вот директива:

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); 
    } 
    } 


} 
3

Извините за несвоевременное реагировать.

Вы можете использовать exportAs meta property в соответствии с директивой, чтобы достичь того, чего хотите.

(я покажу вам соответствующие строки только там, где нужно внести изменения)


/* #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 
}) 

Демо: http://plnkr.co/edit/AE8n4McCez7ioxiTSExL?p=preview

+0

Не могли бы вы быстро проверить и обновить меня, работает ли это для вас или нет, поскольку я хочу заснуть через 5 минут. Просто обновите строки, как я показал вам, затем вы можете проанализировать мое решение позже. – micronyks

+0

Благодарим за сообщение. но я хочу простое решение. в jquery, когда у нас есть элемент '$ element.next()', мы можем выбрать следующий элемент рядом с кнопкой. Я блокирую что-то подобное в угловом2. когда я ищу его найти класс «Renderer», с этим классом я могу выбрать root-элемент сам. это хорошо, но как я могу получить следующий элемент? – Sajad

+0

Зачем вы получаете ссылку на элемент DOM, чтобы сделать это. Лучше использовать мой путь. это просто супер легко. сначала я мог бы выглядеть жестким и жестким, но это очень простое решение. Пожалуйста, не пытайтесь выполнить это jquery way (с угловым2), когда вы можете сделать это с чистым угловым2. – micronyks