繁体   English   中英

将类添加到 Angular2 指令中的下一个元素

[英]Add class to next element in Angular2 Directive

我有一个下拉菜单,我想使用 angular2 指令来处理这个下拉菜单的打开/关闭。 如何将open类添加到latest-notification div 。 通过知道我的指令应用于button标签!

这是我的 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() { }

}

这是我找到的解决方案。 我不认为这是正确的方法或最好的方法。 但至少它起作用了。

现在,通过将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);
    }
  }


}

抱歉回复晚了。

您可以在指令中使用exportAs元属性来实现您想要的。

(我只会在您需要进行更改的地方向您显示相关行)


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

您好,我对@Sajad 的回答进行了改进更新:

  • 角11
  • 引导程序 4
  • 渲染器2
  • 添加类(),删除类()

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>

指示

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM