#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/HTMLInputElement4.
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 проверьте мой обновленный ответ. Я надеюсь, что это поможет вам.