*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對獲取到的元素進行樣式的處理。