Gaya sudut viewContainerRef dari array Input Directive

Nov 12 2020

Saya telah membuat arahan yang menggunakan array panjang variabel untuk mengisi tooltip. Ini berfungsi dengan baik tetapi saya perlu memberi gaya secara dinamis pada tooltip sehingga tetap berada di bawah komponen pemicu awal. Menggunakan nilai atas atau bawah yang berubah berdasarkan jumlah item.

<div tooltipDirective [tooltipDataArray]="['Person1', 'Person2', 'Person3', 'Person4', 'Person5', 'Person6']">See tooltip!
 <ng-template #tooltipTemplate > 
  <div class="tooltip" [ngStyle]="{'top.px': divStyle}">   // Not sure if this is the correct approach as can't bind to divStyle in the directive
  </div>      
 </ng-template>  
</div>

Saya mencoba menggunakan ngStyle tetapi tidak yakin bagaimana cara mendapatkan akses ke nilai divStyle karena ini dibuat menggunakan viewContainerRef.createEmbeddedView.

Saya pikir opsi yang lebih baik adalah menambahkan gaya dari file ts menggunakan style.bottom tetapi saya tidak tahu cara menambahkannya. Saya perlu menghitung tooltipDataArray.length lalu menambahkan 10px atau lebih ke variabel yang mereposisi viewContainerRef. Saya tidak yakin cara terbaik untuk melanjutkan.

 @Input() tooltipDataArray: string[];

 @ContentChild("tooltipTemplate") private tooltipTemplateRef: TemplateRef<Object>;

 @HostListener("mouseenter") onMouseEnter(): void {
  console.log(this.tooltipDataArray);
   const view = this.viewContainerRef.createEmbeddedView(
     this.tooltipTemplateRef
   );

  this.tooltipDataArray.forEach(el => {
  const child = document.createElement("div");
  child.innerText = el;
  this.renderer.appendChild(view.rootNodes[1], child);
  });
  
  // Somthing like this.viewContainerRef.styles.bottom = 10 x this.tooltipDataArray.length + 'px'
  
  console.log(view.rootNodes)
  view.rootNodes.forEach(node => {
  this.renderer.appendChild(this.elementRef.nativeElement, node);
});
}

@HostListener("mouseleave") onMouseLeave(): void {
if (this.viewContainerRef) {
  this.viewContainerRef.clear();
}

stackBlitz di sini

Jawaban

1 Marshal Nov 12 2020 at 17:41

Jika Anda bersedia mengirimkan templateRefsebagai masukan untuk arahan, ini akan jauh lebih mudah ...

Dengan implementasi Anda saat ini, Anda mengganti konten divdengan konten yang dirender dari template ...

  • Ini pada dasarnya bukan tooltip dan Anda harus memisahkannya untuk "mensimulasikan tooltip"

Di bawah ini adalah salah satu cara Anda dapat melakukannya.

Pisahkan ng-templatedari div untuk memisahkannya, dan teruskan #tooltipTemplatesebagai nilai Anda ke [templateRef]masukan didirective

<div tooltipDirective [templateRef]="tooltipTemplate" [tooltipDataArray]="['Person1', 'Person2']">See tooltip!
</div>
<ng-template #tooltipTemplate>      
    <div class="tooltip">   
        This is my tooltip!
    </div>      
</ng-template>  

Dalam direktif Anda, ubah Anda @ContentChildmenjadi input untuk menerima templateRef, membuat, embeddedViewdan menambahkan arrayelemen Anda .

  • Ini juga menyederhanakan logika Anda di sini
  @Input() templateRef: TemplateRef<Object>;

  @HostListener("mouseenter") onMouseEnter(): void {
    const view = this.viewContainerRef.createEmbeddedView(this.templateRef);
    this.tooltipDataArray.forEach(el => {
      const child = document.createElement("div");
      child.innerText = el;
      this.renderer.appendChild(view.rootNodes[1], child);
    });
  }

Sesuaikan gaya global Anda

.tooltip {
  position: absolute;
  /* bottom: -40px; */
  left: 15px;
  padding: 10px;
  background: red;
  border-radius: 5px;
  /* box-shadow: 0 2px 1px rgba(0, 0, 0, 0.6); */
}

STACKBLITZ

https://stackblitz.com/edit/angular-zr2ydx?file=app/tooltip.directive.ts


Ini akan menjadi implementasi terbersih dengan perancah yang Anda berikan ... dengan itu, jika saya menerapkan petunjuk tooltip, saya akan meneliti CDK Overlayuntuk membuat implementasi tooltip kustom.