简体   繁体   中英

Angular Dropdown navigation

I am trying to create a complex breadcrumbs with dropdown-navigation in such way:

在此输入图像描述

I'm struggling with outside click issue: when I need to close dropdown on click somewhere out of the element, BUT if I click another navigation item - it should be open (there is only one opened breadcrumb in same time).

I did in such way:

1) I detect outsideClick by containing an event.target in parent element

2) Switching is happened by closing all breadcrumbs and opened one that is needed.

simple example of breadcrumbs Plunker

timeplate:

     <ul #simpleBreadcrumbs>

      <li *ngFor="let breadcrumb of breadcrumbs"
        class="bread_item"
        (click)="toogleStateOfSubparagraphs(breadcrumb)">

        <div>
          <span>{{breadcrumb.label}}</span>
          <i class="icon-arrows-glyph-1_bold-down"
             *ngIf="!breadcrumb.isOpen">
          </i>
          <i class="icon-arrows-glyph-1_bold-up"
             *ngIf="breadcrumb.isOpen">
          </i>
        </div>


        <ul class="switcher__list dropdown__list"
            *ngIf="breadcrumb.isOpen">
          <li class="switcher__item dropdown__item" *ngFor="let subparagraph of breadcrumb.subparagraphs">
            <a class="switcher__item-href">
              {{subparagraph.label}}
            </a>
        </li>
    </ul>

  </ul>

component class:

export class App {
  breadcrumbs:any[];

  @ViewChild('simpleBreadcrumbs') private _breadcrumbsTemplate: ElementRef;
  _currentOpenedBreadcrumbs:any;

  constructor() {
    this.breadcrumbs = [
      {
        label: 'First',
        isOpen: false,
        subparagraphs: [
          {
            label: '1.1'
          },
          {
            label: '1.2'
          }]
      },
      {
        label: 'Second',
        isOpen: false,
        subparagraphs: [
          {
            label: '2.1'
          },
          {
            label: '2.2'
          }]
      }];
  }

  toogleStateOfSubparagraphs(breadcrumb) {
     if (this._currentOpenedBreadcrumbs === breadcrumb) {
      this._closeSubparagraphs();
      this._currentOpenedBreadcrumbs = null;
      return;
    }
    this.breadcrumbs
      .forEach((bread: IBreadCrumb) => {
        bread.isOpen = false;
        if (bread === breadcrumb) {
          bread.isOpen = true;
        }
      });
    this._currentOpenedBreadcrumbs = breadcrumb;
  }

  _closeSubparagraphs() {
    this.breadcrumbs
      .map((bread) => {
        bread.isOpen = false;
        return bread;
      });
  }

  @HostListener('window:keydown', ['$event'])
  public onEscapeClick(event: KeyboardEvent): void {
    if (event.which === 27 && !this._breadcrumbsTemplate.nativeElement.contains(event.target as Node)) {
      this._closeSubparagraphs();
    }
  }

  @HostListener('document:click', ['$event'])
  public onOutsideClick(event: Event): void {
   if (!this._breadcrumbsTemplate.nativeElement.contains(event.target as Node)) {
      this._closeSubparagraphs();
    }
  }
}

I changed your CSS file to:

.bread_item {
 list-style: none;
 float: left;
 padding: 30px;

}

Is this what you were looking for? If not, than i might have misinterpreted your question.

Your previous css made it so that the second element was also pushed down on clicking the first element.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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