簡體   English   中英

Angular @viewChild 元素的 "nativeElement: 和 "value" 未定義

[英]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);
}

如代碼所示,日志都返回undefinedfalse 這是我正在使用的實際 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM