綁定dom angular 【結構型指令】@ViewChild ElementRef *ngTemplateOutlet

 *ngTemplateOutlet 

Angular template outlets can be used to insert a common template in various sections of a view that are not generated by a loop or subject to a condition. For example, you can define a template for the logo of a company and insert it in several places.

模板可以像任何其他DOM元素或組件一樣注入,通過提供模板引用名稱 defaultTabButtons 到 ViewChild 裝飾器。

這意味着模板也可以在組件類的級別訪問,並且我們可以做一些事情,例如將它們傳遞給子組件。

參考鏈接:https://blog.angular-university.io/angular-ng-template-ng-container-ngtemplateoutlet/

父組件A:

// html:
<ng-template #customTabButtons>
      {{ test }}
    </ng-template>

<app-maintenance-user-hint
      [headerTemplate]="customTabButtons"
></app-maintenance-user-hint>

// ts:
  test="from warm up";

 子組件:

// html:
<ng-template #defaultTabButtons>
  <div class="default-tab-buttons">
    default ...
  </div>
</ng-template>

<ng-container
  *ngTemplateOutlet="headerTemplate ? headerTemplate : defaultTabButtons"
>
</ng-container>

// ts:
@Input() headerTemplate?: TemplateRef<any>;

 顯示:

只有在設置了headerTemplate的父組件,纔會渲染:from warm up,其它父組件的話就渲染:default...


ngAfterViewInit() {
    fromEvent<WheelEvent>(
      this.el.nativeElement.querySelector('.title-box'),
      'wheel'
    )
      .pipe(filter(e => e.deltaY > 0))
      .subscribe(() => {
        this.el.nativeElement.querySelector('.title-box').scrollLeft += 100;
      });

    fromEvent<WheelEvent>(
      this.el.nativeElement.querySelector('.title-box'),
      'wheel'
    )
      .pipe(filter(e => e.deltaY < 0))
      .subscribe(() => {
        this.el.nativeElement.querySelector('.title-box').scrollLeft -= 100;
      });
  }

之前一直沒有 querySelector成功 是沒有在渲染後添加


@ViewChild

@ViewChild和@ViewChildren用於從模板視圖中獲取匹配的元素,在父組件鉤子方法ngAfterViewInit調用之前賦值。

常用的選擇器:class,模板引用變量,TemplateRef。

 

使用:

1. DOM

如果想通過@ViewChild、@ViewChildren訪問到DOM節點的話都得先給相應的DOM節點設置模板引用變量。
  • 獲取宿主視圖
// html:
// <div #domLabel>abc</div>

 @ViewChild('domLabel', { static: true }) domLabelChild: ElementRef;
 ngAfterViewInit(): void {
    // DOM節點
    console.log(this.domLabelChild.nativeElement);
  }
  • 獲取嵌入視圖
// html
//<ng-template #domTemplate><div>默認我是不會顯示的</div></ng-template>

  /**** DOM節點對應的 ****/
  @ViewChild('domTemplate', { static: true }) domTemplate: TemplateRef<any>; // 查找嵌入元素
  /**** @ViewChild(TemplateRef) @ViewChildren(TemplateRef)獲取頁面上的ng-template節點信息 ****/
  @ViewChild(TemplateRef, { static: true }) template: TemplateRef<any>;
  ngAfterViewInit(): void {
    // DOM節點
    console.log(this.domTemplate);
    console.log(this.template);
  }
 

2. 父組件通過@viewChild調用子組件 

// html:
// <app-child #appChild></app-child>
// <div (click)="test()">父組件的btn</div>

/**** 組件 ****/
  @ViewChild('appChild', { static: true }) componentChild: ChildComponent; // 找到一個子組件
  @ViewChild('appChild', {read: ElementRef,static:true}) componentChildElement: ElementRef; // 直接找到子組件的DOM

test() {
    this.appChild.go();
}


// 以上是父組件。以下是子組件

go() {
console.log(233)
}

The core directives ng-container, ng-template and ngTemplateOutlet all combine together to allow us to create highly dynamical and customizable components.

The <ng-template> is an Angular element for rendering HTML. It is never displayed directly. Use for structural directives such as: ngIf, ngFor, ngSwitch,..


ElementRef類

通過 ElementRef 我們就可以封裝不同平臺下視圖層中的 native 元素 (在瀏覽器環境中,native 元素通常是指 DOM 元素),最後藉助於 Angular 提供的強大的依賴注入特性,我們就可以輕鬆地訪問到 native 元素。

console.log(this.elementRef.nativeElement.querySelector(‘div’)); 在AfterViewInit 鉤子裏獲取到div這個dom元素。

另外可通過Renderer2提供的API對獲取到的元素進行樣式的處理。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章