Angular: 在 ng-template 中访问 elementRef
Angular: Access elementRef inside an ng-template
我通过 ng-template
获得了一个呈现不同表单字段组件的组件。现在我想访问最后呈现的组件中的一个函数。
我尝试使用带有字符串 select 的 ViewChildren()
注释访问它,或者所有字段组件(文本字段,select 字段)扩展自。
allFields
始终为空。还尝试以 ContentChildren
和 AfterContentInit
生命周期挂钩访问它。任何想法如何实现这一目标?
这很像 this 问题,但仍未得到解答,所以我想我会再问一遍。谢谢
HTML
<div *ngFor="let field of fields; fieldIndex as index">
<ng-container *ngTemplateOutlet="getTemplate()"></ng-container>
</div>
<input type="button" (click)="doFunctionOnLastField()">
<ng-template #text>
<text-field #field [field]=this.fields[fieldIndex]></text-field>
<ng-template>
<ng-template #select>
<select-field #field [field]=this.fields[fieldIndex]></text-field>
<ng-template>
TypeScript
export class FormComponent implements OnInit, AfterViewInit {
@Input() fields: FieldBase[];
@ViewChild('text') text: TemplateRef<any>
@ViewChild('select') select: TemplateRef<any>
@ViewChildren('field') allFields;
lastField: FieldBaseComponent;
fieldIndex: number = 0;
ngOnInit(): void {
//...
}
ngAfterViewInit(): void {
this.lastField = this.allFields.last; //this.allFields is empty
}
getTemplate() {
// returns my template
}
doFunctionOnLastField() {
this.lastField.someFunctionInsideTheField(); //this.lastField... is undefined
}
}
呈现的视图及其子视图仅在模板在 ViewContainerRef
中呈现时才可访问,因此 right here.
使用ngTemplateOutlet
时无法获得渲染视图,所以我认为最好的办法是复制代码并修改它以满足您的要求。
getTemplate()
方法将在调用 ngAfterViewInit()
之前被调用。
当 getTemplate()
第一次被调用时,它甚至不会 return TemplateRef,只有在下一个变化检测周期中,TemplateRef 才会正确 return ed 并且您的字段将被渲染。您甚至可能会遇到 ExpressionChangedAfterItHasBeenCheckedError 错误。
因此,当 ngAfterViewInit
被调用时,您的字段不会被渲染,因此 this.allFields.last
将是未定义的。
尝试为 text
和 select
ViewChild 声明将 static
元数据 属性 指定为 true
:
@ViewChild('text', { static: true }) text: TemplateRef<any>;
@ViewChild('select', { static: true }) select: TemplateRef<any>;
我通过 ng-template
获得了一个呈现不同表单字段组件的组件。现在我想访问最后呈现的组件中的一个函数。
我尝试使用带有字符串 select 的 ViewChildren()
注释访问它,或者所有字段组件(文本字段,select 字段)扩展自。
allFields
始终为空。还尝试以 ContentChildren
和 AfterContentInit
生命周期挂钩访问它。任何想法如何实现这一目标?
这很像 this 问题,但仍未得到解答,所以我想我会再问一遍。谢谢
HTML
<div *ngFor="let field of fields; fieldIndex as index">
<ng-container *ngTemplateOutlet="getTemplate()"></ng-container>
</div>
<input type="button" (click)="doFunctionOnLastField()">
<ng-template #text>
<text-field #field [field]=this.fields[fieldIndex]></text-field>
<ng-template>
<ng-template #select>
<select-field #field [field]=this.fields[fieldIndex]></text-field>
<ng-template>
TypeScript
export class FormComponent implements OnInit, AfterViewInit {
@Input() fields: FieldBase[];
@ViewChild('text') text: TemplateRef<any>
@ViewChild('select') select: TemplateRef<any>
@ViewChildren('field') allFields;
lastField: FieldBaseComponent;
fieldIndex: number = 0;
ngOnInit(): void {
//...
}
ngAfterViewInit(): void {
this.lastField = this.allFields.last; //this.allFields is empty
}
getTemplate() {
// returns my template
}
doFunctionOnLastField() {
this.lastField.someFunctionInsideTheField(); //this.lastField... is undefined
}
}
呈现的视图及其子视图仅在模板在 ViewContainerRef
中呈现时才可访问,因此 right here.
使用ngTemplateOutlet
时无法获得渲染视图,所以我认为最好的办法是复制代码并修改它以满足您的要求。
getTemplate()
方法将在调用 ngAfterViewInit()
之前被调用。
当 getTemplate()
第一次被调用时,它甚至不会 return TemplateRef,只有在下一个变化检测周期中,TemplateRef 才会正确 return ed 并且您的字段将被渲染。您甚至可能会遇到 ExpressionChangedAfterItHasBeenCheckedError 错误。
因此,当 ngAfterViewInit
被调用时,您的字段不会被渲染,因此 this.allFields.last
将是未定义的。
尝试为 text
和 select
ViewChild 声明将 static
元数据 属性 指定为 true
:
@ViewChild('text', { static: true }) text: TemplateRef<any>;
@ViewChild('select', { static: true }) select: TemplateRef<any>;