[英]Angular @viewChild element's "nativeElement: and "value" are undefined
我在我的組件中使用 @ViewChild 引用:
@ViewChild('tableCellWidget', { static: false }) tableCellWidget: ElementRef<HTMLInputElement>;
我正在嘗試訪問我附加了tableCellWidget
viewChild 引用的元素的“值”,以便將尾隨 span 元素的[innerHTML]
動態設置為通過<select-widget-widget>
加載的表單元素的當前值下面<select-widget-widget>
模板(這是在動態生成的 mat-table 的循環內:
<td mat-cell *matCellDef="let data; let rowIndex = index">
<ng-container *ngIf="column !== ACTIONS_COLUMN_NAME">
<div *ngIf="layout[i] && layout[i].widget">
<select-widget-widget
#tableCellWidget
[class]="dragDropEnhancedMode && childTemplateModel ? getActiveItemClass(childTemplateModel[i]) : ''"
(change)="onCellChange($event, rowIndex, column)"
[logic]="layout[i]?.options?.logic || {}"
[rowIndex]="rowIndex + paginationRowOffset"
[dataIndex]="[].concat(rowIndex + paginationRowOffset)"
[layoutIndex]="(layoutIndex || []).concat(i)"
[layoutNode]="layout[i]">
</select-widget-widget>
<span *ngIf="tableConfig?.columnTypes[column] === 'default'" [innerHTML]="getPlainText()"></span>
</div>
</ng-container>
</td>
這是 innerHTML 調用的代碼:
getPlainText() {
const myValue = this.tableCellWidget?.nativeElement?.value || 'no value';
const myValue2 = this.tableCellWidget?.nativeElement;
console.log('tableCellWidget value', myValue); // UNDEFINED
console.log('tableCellWidget nativeElement', myValue2); // UNDEFINED
console.log('this.getPlainTextHasValue', this.getPlainTextHasValue); // FALSE
return myValue;
}
get getPlainTextHasValue(): boolean {
// returns false;
return hasValue(this.tableCellWidget?.nativeElement?.value);
}
如代碼所示,日志都返回undefined
和false
。 這是我正在使用的實際 DOM html 的示例,以及我試圖用來在跨度上設置 innerHTML 的元素:
<div _ngcontent-sen-c24="" class="ng-star-inserted">
<!--bindings={
"ng-reflect-ng-if": "false"
}-->
<select-widget-widget _ngcontent-sen-c24="" ng-reflect-layout-node="[object Object]" ng-reflect-layout-index="0,1" ng-reflect-data-index="0" ng-reflect-row-index="0" ng-reflect-logic="[object Object]" class="">
<!---->
<hidden-widget _nghost-sen-c37="" class="ng-star-inserted">
<input _ngcontent-sen-c37="" type="hidden" value="Rob Bischoff-4" ng-reflect-form="[object Object]" id="control1660760198229_1660760203705" name="accountName" class="ng-untouched ng-dirty ng-valid"><!--bindings={
"ng-reflect-ng-if": "false"
}-->
</hidden-widget>
</select-widget-widget>
</div>
非常感謝任何幫助。 我的方法顯然缺少一些東西。
更新:我的組件中有另一個 viewChild 元素。 看來,當我比較該元素和我的元素的 console.logs 時,我可以看到它們有很大不同。 看來我的 viewchild 引用的是 angular 模板與它所代表的底層原生元素? 從下圖中,您可以看到 this.filterRef 與 this.tableCellWidget 的日志 output。 這對我來說很明顯,為什么它未定義但不明顯我如何獲得對底層元素的引用。
這是因為您引用的是組件,而不是 HTML 元素。 Angular 的設計使得組件之間是“黑匣子”。 Angular 的方式是讓子代向父代發出值,而不是直接通過 html 查詢值。
我不知道select-widget-widget
的內部工作原理,所以我無法准確地告訴你該怎么做,但它應該有一個事件發射器,只要它發生變化就會發出該值。 然后,您在更改時更新的父級中只有一個屬性。 也許(change)
已經在這樣做了,您只需要更新onCellChange()
中的屬性。
例子:
<select-widget-widget
(valueChange)='widgetValue = $event'
...
></select-widget-widget>
<span [innerHTML]="widgetValue"></span>
// Component TS
widgetValue = ''
或者如果change
已經發出值:
<select-widget-widget
(change)="onCellChange($event, rowIndex, column)"
...
></select-widget-widget>
<span [innerHTML]="widgetValue"></span>
widgetValue = '';
onCellChange(ev, row, col) {
this.widgetValue = ev;
...
}
但當然你不必以 Angular 的方式做事。 你總是可以只使用 vanilla JS。
<select-widget-widget
id='tableCellWidget'
...
></select-widget-widget>
<span [innerHTML]="tableCellWidget?.value"></span>
tableCellWidget?: HTMLInputElement;
ngAfterViewInit() {
this.tableCellWidget = document.querySelector(
'#tableCellWidget > hidden-widget > input'
);
}
警告:使用這種方法,視圖封裝會出現在 window 中。 如果有多個小部件,您需要確保它們都有唯一的 id,否則您將度過難關。 您可以只 append id 獨有的東西,如列/行號。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.