简体   繁体   English

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

[英]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 的回答进行了改进更新:

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

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.

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