มุมมองรูปแบบเชิงมุมContainerRefจาก Directive Input array

Nov 12 2020

ฉันได้สร้างคำสั่งที่ใช้อาร์เรย์ความยาวตัวแปรเพื่อเติมคำแนะนำเครื่องมือ วิธีนี้ใช้งานได้ดี แต่ฉันต้องจัดรูปแบบคำแนะนำเครื่องมือแบบไดนามิกเพื่อให้อยู่ภายใต้องค์ประกอบทริกเกอร์เริ่มต้น ใช้ค่าบนสุดหรือล่างสุดที่เปลี่ยนไปตามจำนวนรายการ

<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>

ฉันลองใช้ ngStyle แต่ไม่แน่ใจว่าจะเข้าถึงค่า divStyle ได้อย่างไรเพราะสิ่งนี้สร้างขึ้นโดยใช้ viewContainerRef.createEmbeddedView

ฉันคิดว่าตัวเลือกที่ดีกว่าคือการเพิ่มสไตล์จากไฟล์ ts โดยใช้ style.bottom แต่ฉันไม่รู้จะเพิ่มอย่างไร ฉันต้องการคำนวณ tooltipDataArray.length จากนั้นเพิ่ม 10px หรือมากกว่านั้นให้กับตัวแปรที่เปลี่ยนตำแหน่ง viewContainerRef ฉันไม่แน่ใจว่าจะดำเนินการอย่างไรดีที่สุด

 @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 ที่นี่

คำตอบ

1 Marshal Nov 12 2020 at 17:41

หากคุณยินดีที่จะส่งtemplateRefเป็นข้อมูลเข้าสู่คำสั่งสิ่งนี้จะง่ายกว่ามาก ...

ด้วยการใช้งานปัจจุบันของคุณคุณกำลังแทนที่divเนื้อหาของเทมเพลตด้วยเนื้อหาที่แสดงผลของเทมเพลต ...

  • โดยพื้นฐานแล้วนี่ไม่ใช่คำแนะนำเครื่องมือและคุณจะต้องแยกออกเพื่อ "จำลองคำแนะนำเครื่องมือ"

ด้านล่างนี้เป็นวิธีหนึ่งที่คุณสามารถทำได้

แยกng-templateจาก div เพื่อแยกออกและส่ง#tooltipTemplateเป็นค่าของคุณไปยัง[templateRef]อินพุตบนไฟล์directive

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

ในคำสั่งของคุณแปลงของคุณ@ContentChildเป็นอินพุตเพื่อรับtemplateRefสร้างembeddedViewและเพิ่มarrayองค์ประกอบของคุณ

  • นอกจากนี้ยังช่วยลดความซับซ้อนของตรรกะของคุณที่นี่
  @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);
    });
  }

ปรับสไตล์สากลของคุณ

.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


นี่จะเป็นการใช้งานที่สะอาดที่สุดกับโครงนั่งร้านที่คุณให้มา ... จากที่กล่าวว่าถ้าฉันจะใช้คำสั่งคำแนะนำเครื่องมือฉันจะค้นคว้าCDK Overlayเพื่อสร้างการใช้งานคำแนะนำเครื่องมือที่กำหนดเอง