Angular 10: ошибка [objet HTMLInputElement]

#javascript #angular #typescript

#javascript #угловатый #typescript

Вопрос:

Я работаю с angular 10 и хочу добавить строку с типом ввода в мою существующую таблицу, когда я нажимаю на кнопку добавить.

Вот мой код :

 export class CsContextComponent implements OnInit, OnDestroy {

@ViewChild('table') table!: MatTable<string>;
contextAttributeKeys!: IContextAttributeKey[];
controls!: FormArray;
displayedColumns: string[] = ['priority', 'name', 'description', 'actions'];
dataSource = new MatTableDataSource<ContextAttributeKey>();
dataSchema!: IContextAttributeKey[];
contextAttributeKeys!: IContextAttributeKey[];

addTable(): void {
    const inputName: any = document.createElement("input");
    inputName.type = "text";
    const inputDescription: any = document.createElement("input");
    inputDescription.type = "text";
    const priority: any = this.contextAttributeKeys.length   1;
    const table: HTMLTableElement = document.getElementById("table") as 
    HTMLTableElement;

    this.contextAttributeKeys.push(new ContextAttributeKey(999, inputName, 
     inputDescription, priority));
     this.table.renderRows();
}
 

HTML :

          <form name="editForm" role="form" [formGroup]="editForm">
         <table mat-table class="table table-bordered table-striped" 
         id="table" #table [dataSource]="contextAttributeKeys" cdkDropList 
         (cdkDropListDropped)="drop($event)">
            <!-- Priority Column -->
            <ng-container matColumnDef="priority">
              <th class="col-xs" *matHeaderCellDef> Priority </th>
              <td mat-cell *matCellDef="let element;let i = index">
                <div class="drag-handle">
                  <ng-container  [ngTemplateOutlet]="dragHandleTmpl">
                  </ng-container>
                {{ element.priority }}
              </div>
              </td>
            </ng-container>

            <!-- Name Column -->
            <ng-container matColumnDef="name">
              <th scope="col" *matHeaderCellDef> Name </th>
              <td class="col-md" mat-cell *matCellDef="let element;let i = 
              index" id="nameTd">
                <span> 
                  {{element.name}}
                
                </span>
              </td>
              </ng-container>

            <!-- Description Column -->
            <ng-container matColumnDef="description">
              <th scope="col" *matHeaderCellDef> Description </th>
              <td class="col-md" mat-cell *matCellDef="let element;let i = 
              index" id="descriptionTd">
                <span>
                    {{element.description}}
                  </span>
              </td>
            </ng-container>
            <!-- Action Column -->
            <ng-container matColumnDef="actions">
              <th scope="col" *matHeaderCellDef>Actions</th>
              <td class="col-xs text-right" mat-cell *matCellDef="let 
              element;let i = index">
                <div>
                <button (click)="onEdit(i)" class="btn btn-warning btn- 
                mini"><i 
                 class="fa fa-edit"></i></button>
                <button (click)="delete(element)" class="btn btn-danger btn- 
                mini"><i class="fa fa-trash"></i></button>
                </div>
       
              </td>
            </ng-container>

            <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
            <tr mat-row *matRowDef="let row; columns: displayedColumns;" 
           cdkDrag [cdkDragData]="row" id="tr"></tr>
          </table>
        </form>
          <br>
    <button id="jh-create-entity" class="btn btn-context shape-semi-round 
    float-right jh-create-entity create-context-attribute-key" 
    (click)="addTable()">
        <fa-icon icon="plus"></fa-icon>
        <span>
        Add
        </span>
    </button>
 

это моя таблица

когда я нажимаю кнопку добавить, я хочу добавить новую строку с увеличенным приоритетом и 2 полями ввода для нового имени и описания, мне удалось добавить строку и увеличить и изменить приоритет, но я не смог показать поля ввода, которые я получил [object HTMLInputELEMENT] вместо фактического поля ввода.

Помогите, пожалуйста!

Комментарии:

1. HTMLInputElement является ли тип элемента ввода (и это правильный тип), поэтому я не вижу, что не так? Кроме того, я бы рекомендовал не использовать этот подход к созданию элементов в Angular (прямое манипулирование DOM не рекомендуется), а создать отдельный компонент и фабрику компонентов.

2. когда я нажимаю inputName и inputDescription в contextAttributeKeys, я получаю [object HTMLInputElement] не фактический ввод для записи.. я добавлю изображение таблицы, чтобы показать вам

3. Input является объектом типа HTMLInputElement , означающего, что это javascript-представление <input> элемента в html. Он предоставляет все свойства, которые описывают ввод в html. Взгляните на документацию (например value , свойство для текста ввода): developer.mozilla.org/de/docs/Web/API/HTMLInputElement

4. const inputName: any на самом деле это было бы const inputName: HTMLInputElement в вашем коде (то же самое для inputDescription). Я бы рекомендовал изменить это, потому что это даст вам intellisense, например, для .type .

5. спасибо за ваши ответы, но я не хочу, чтобы значение ввода, которое я хочу в него записать. я отображаю данные в своей таблице MATT (angular material), и у меня есть кнопка addButton, когда я нажимаю на нее, отображается новая строка с увеличением приоритета и полем ввода для добавления имени и описания

Ответ №1:

С дополнительным кодом проблемы кажутся более понятными.

Вы пытаетесь использовать ввод в виде строки (такой же, как вы бы ввели в консоли браузера document.createElement('input').toString() ). Вам нужно будет получить .outerHTML из созданного вами входного узла, а затем передать это через Angular Sanitizer, чтобы создать экземпляр SafeHtml, а затем вы могли бы привязать его к [innerHTML] вводу любого элемента в шаблоне (возможно <div> ).

Вместо этого вам следует либо написать полностью новое определение строки, либо добавить продолжение внутри каждой ячейки для замены {{element.priority}} на определение ввода (что-то вроде):

         <ng-container matColumnDef="priority">
          <th class="col-xs" *matHeaderCellDef> Priority </th>
          <td mat-cell *matCellDef="let element;let i = index">
            <div class="drag-handle">
              <ng-container  [ngTemplateOutlet]="dragHandleTmpl">
              </ng-container>

              <ng-container *ngIf="element.editMode">
                <input type="text" formControlName="priority" />
              </ng-container>
              <ng-container *ngIf="!element.editMode">
                {{ element.priority }}
              </ng-container>

            </div>
          </td>
        </ng-container>
 

Рассматривайте это как предложение, а не как окончательное решение. Таким образом, вы сохраняете угловые привязки и обработку формы и не касаетесь необработанных узлов DOM.

ОРИГИНАЛЬНЫЙ ОТВЕТ НИЖЕ: ——————————————

Не уверен, почему вы напрямую касаетесь API-интерфейсов окон и необработанных узлов DOM, но ваша проблема, похоже, вызвана очисткой DOM или выводом HTML в виде узлов вместо строки в угловые привязки. Потребуется более широкий контекст.

В общем, концепция этого в Angular заключается в использовании компонентов и привязки данных для каждого элемента.

Что — то вроде этого:

(app-table.component.html )

 <table formArrayName="list">
  <tr *ngFor="let contextAttribute of contextAttributeKeys; let i = index">
    <td><input type="text" [formControlName]="i" [value]="contextAttribute.priority"></td>
  </tr>
</table>
 

(app-table.component.ts)

 import { Component, OnInit } from '@angular/core';
import { FormArray, FormGroup } from '@angular/forms';

@Component({
  selector: 'app-table',
  templateUrl: './app-table.component.html',
  styleUrls: ['./app-table.component.scss']
})
export class AppTableComponent implements OnInit {

  form: FormGroup;
  contextAttributeKeys: any[];

  constructor() { }

  ngOnInit(): void {
    this.contextAttributeKeys = [
      {
        priority: 222,
      },
      {
        priority: 4,
      }
    ];

    this.form = new FormGroup({
      list: new FormArray([])
    });
  }

}
 

Это всего лишь пример, пожалуйста, прочитайте больше об угловом способе обработки форм:
https://angular.io/start/start-forms

Комментарии:

1. спасибо за ваши ответы, но это не то, что я хочу. я отображаю данные в своей таблице matTable (angular material), и у меня есть кнопка addButton, когда я нажимаю на нее, отображается новая строка с увеличением приоритета и полем ввода для добавления имени и описания

2. @symfony пожалуйста, покажите остальную часть кода, потому что не похоже, что ваша таблица была создана с использованием углового подхода. В моем коде, чтобы добавить еще один ввод, вам просто нужно поместить другой объект в массив contextAttrubuteKeys, angular обработает все представление

3. @symfony проверьте мой обновленный ответ. Я надеюсь, что это поможет вам.