Вызов угловой директивы несколько раз

#angular #angular-directive

#угловой #угловая директива

Вопрос:

tree-view.html

 <div *ngFor="let item of nodes; let i=index" class="parent" [id]="item.name" appTreeView>
        {{item.name}}
        <div class="child" *ngIf="item.child">
            <app-tree-view [nodes]="item.child"></app-tree-view>  // recursive call 
        </div>
</div>
  

treeview.ts

 this.data=[
      {
        name:"level 1",
        child:[
          {
            name:"level 1.1",
          }
        ]
      },
      {
        name:"level 2",
        child:[
          {
            name:"level 2.1",
            child:[
              {
                name:"level 2.1.1"
              }
            ]
          }
        ]
      }
    ]
  

directive.ts

 import { Directive, HostListener,Renderer2 } from '@angular/core';

@Directive({
  selector: '[appTreeView]',
})
export class TreeViewDirective {

  constructor(private render:Renderer2) { }
  @HostListener('click',['$event'])
  check(event){
    console.log(event.target.id);
    const avalclass:string=event.target.classList.value;
    if(avalclass.includes('expand')){
      this.render.removeClass(event.target,'expand');
    }else{
      this.render.addClass(event.target,'expand');
    }
    
  }
}

  

Вывод

  • Уровень 1
  • Уровень 2

Если я нажму уровень 2 развернуть подменю уровень 2.1 консоль печать один раз

  • Уровень 1
  • Уровень 2
    • Уровень 2.1

затем я нажимаю уровень 2.1 развернуть подменю 2.1.1 консоль печать два раза

  • Уровень 1
  • Уровень 2
    • Уровень 2.1
      • Уровень 2.1.1

Почему консоль печатает несколько раз. в чем мои ошибки

Ответ №1:

Консоль печатает несколько раз одно и то же, потому что вы используете рекурсию для вызова родителя и его потомков. Вы привязываете событие щелчка несколько раз в зависимости от того, на каком уровне находится элемент, на который вы нажимаете. Если вы знаете о потоке вашего кода:

  • Если щелкнуть элемент первого уровня (уровень 1 или уровень 2): он печатается один раз.
  • Если вы нажмете на элемент второго уровня (уровень 1.1 или уровень 2.2): он печатает два раза, один для второго уровня, а другой для первого.
  • И так далее..

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

https://stackblitz.com/edit/angular-recursion-directives?file=src/app/tree-view.directive.ts

Вы могли бы решить эту проблему, добавив флаг в свою директиву и проверив его в своей функции проверки:

 if (this.isFired) {
      return;
    }
this.isFired = true;
  

Или сравнение текущего основного элемента и элемента, который вызвал событие:

 if(this.el.nativeElement.id == event.target.id){
   console.log("click on: "   event.target.id);
      const avalclass: string = event.target.classList.value;

      if (avalclass.includes("expand")) {
        this.render.removeClass(event.target, "expand");
      } else {
        this.render.addClass(event.target, "expand");
      }
    }
}
  

Комментарии:

1. Да, я привязываю несколько раз, используя рекурсивную функцию, так как я могу решить эту проблему.