Angular NgModel 绑定无法读取未定义的 属性
Angular NgModel Binding cannot read property of undefined
所以我正在尝试从我拥有的项目数组中编辑一个项目,但我不知道如何绑定 NgModel
此外,它正在通过 Material 对话框 window 进行编辑。
这是我正在使用的 TS 文件:
import { Component, OnInit , Inject , Input } from '@angular/core';
import {MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog';
import { StorageItem } from '../../StorageItem';
import { ItemsService } from '../items.service';
import { Items } from '../../MockItems';
import { Observable, Subject } from 'rxjs';
export interface DialogData {
Unit: string;
Name: string;
Amount: number;
}
@Component({
selector: 'app-dialog-window',
templateUrl: './dialog-window.component.html',
styleUrls: ['./dialog-window.component.css']
})
export class DialogWindowComponent implements OnInit {
Unit: string;
Name: string;
Amount: number;
selected: StorageItem;
constructor(public dialog: MatDialog , public itemsService: ItemsService) {}
openDialog(hero: StorageItem): void {
this.selected = hero;
console.log(this.selected.Name);
const dialogRef = this.dialog.open(DialogComponent, {
width: '250px',
data: {Unit: this.Unit, Amount: this.Amount, Name: this.Name}
});
dialogRef.afterClosed().subscribe(Unit => {
console.log('The dialog was closed');
this.Unit = Unit;
});
}
ngOnInit(): void {}
}
@Component({
selector: 'app-dialog',
templateUrl: 'DialogEdit.html',
})
export class DialogComponent {
$Items: StorageItem;
constructor(
public dialogRef: MatDialogRef<DialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: DialogData) {
}
onNoClick(): void {
this.dialogRef.close();
}
}
Html用按钮打开对话框:
<li>
<button mat-raised-button (click)="openDialog()">Edit Item</button>
</li>
对话框内部的Html:
<div mat-dialog-content>
<p>Name</p>
<mat-form-field>
<mat-label>Name</mat-label>
<input matInput [(ngModel)]="Items.Name">
</mat-form-field>
</div>
不知道该不该Items.Name我只是举个例子
数组看起来像这样:
import { StorageItem } from './StorageItem';
export const Items: StorageItem[] = [
{ Quantity: 11, Name: 'Sand', Unit: 'kg'},
{ Quantity: 6, Name: 'Lamps', Unit: 'pcs'},
{ Quantity: 18, Name: 'Rocks', Unit: 'kg'},
{ Quantity: 2, Name: 'Tables', Unit: 'pcs'},
{ Quantity: 2, Name: 'Water', Unit: 'l'},
{ Quantity: 200, Name: 'Rope', Unit: 'm'},
];
StorageItem 界面是这样的:
export interface StorageItem {
Name: string;
Quantity: number;
Unit: string;
}
所以我想要实现的是打开对话框 window 并输入名称,以便我可以更改它并关闭对话框。如果它仅用于会话也很好,我不需要它来更改文件。重新加载后它可以恢复为默认值。
如果我输入 data.Unit 它会起作用,但这不是我想将它绑定到项目名称并更改它的重点。
有一个 table genrated let StorageItem of Items 加上按钮所以每个对象旁边都有按钮。
我试过像在英雄之旅中所做的那样
selected: StorageItem
funcionOnclickToOpenDialog(storageItem: StorageItem){
this.selected = storageItem;
}
但这也没有用。
如果有任何遗漏或您希望我澄清,我将很乐意提供帮助。
您编辑的是名称而不是单位:)
dialogRef.afterClosed().subscribe(Unit => {
console.log('The dialog was closed');
this.Unit = Unit;
});
你应该把上面的改成这样:
dialogRef.afterClosed().subscribe(name => {
console.log('The dialog was closed');
this.Name = name;
});
项目应该是 class 变量才能在模板中使用。
我在这里看到 Items 是用 const 声明的。应该是
Items: StorageItem[] = [
{ Quantity: 11, Name: 'Sand', Unit: 'kg'},
{ Quantity: 6, Name: 'Lamps', Unit: 'pcs'},
{ Quantity: 18, Name: 'Rocks', Unit: 'kg'},
{ Quantity: 2, Name: 'Tables', Unit: 'pcs'},
{ Quantity: 2, Name: 'Water', Unit: 'l'},
{ Quantity: 200, Name: 'Rope', Unit: 'm'},
];
问题出在我的 html 中,当使用 ng-container 时,表单开始变得奇怪。
现在,当我递归地生成我的 html 时,这个解决方案有效:
<ng-template #formCategoryTemplate let-formCategory>
<div [formGroup]="getFormGroup(formCategory)" class="request-form">
</ng-container>
<tr class="input" *ngIf="isInput(formEntry)">
<td>
<mat-form-field appearance="outline" class="full-width">
<input [formControl]="getFormControl(toInput(formEntry))" matInput>
</mat-form-field>
</td>
</tr>
</ng-container>
</div>
</ng-template>
toIput 将只接受条目,return entry as InputEntry
getFormGroup 将 return myFormGroup
所以我正在尝试从我拥有的项目数组中编辑一个项目,但我不知道如何绑定 NgModel 此外,它正在通过 Material 对话框 window 进行编辑。 这是我正在使用的 TS 文件:
import { Component, OnInit , Inject , Input } from '@angular/core';
import {MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog';
import { StorageItem } from '../../StorageItem';
import { ItemsService } from '../items.service';
import { Items } from '../../MockItems';
import { Observable, Subject } from 'rxjs';
export interface DialogData {
Unit: string;
Name: string;
Amount: number;
}
@Component({
selector: 'app-dialog-window',
templateUrl: './dialog-window.component.html',
styleUrls: ['./dialog-window.component.css']
})
export class DialogWindowComponent implements OnInit {
Unit: string;
Name: string;
Amount: number;
selected: StorageItem;
constructor(public dialog: MatDialog , public itemsService: ItemsService) {}
openDialog(hero: StorageItem): void {
this.selected = hero;
console.log(this.selected.Name);
const dialogRef = this.dialog.open(DialogComponent, {
width: '250px',
data: {Unit: this.Unit, Amount: this.Amount, Name: this.Name}
});
dialogRef.afterClosed().subscribe(Unit => {
console.log('The dialog was closed');
this.Unit = Unit;
});
}
ngOnInit(): void {}
}
@Component({
selector: 'app-dialog',
templateUrl: 'DialogEdit.html',
})
export class DialogComponent {
$Items: StorageItem;
constructor(
public dialogRef: MatDialogRef<DialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: DialogData) {
}
onNoClick(): void {
this.dialogRef.close();
}
}
Html用按钮打开对话框:
<li>
<button mat-raised-button (click)="openDialog()">Edit Item</button>
</li>
对话框内部的Html:
<div mat-dialog-content>
<p>Name</p>
<mat-form-field>
<mat-label>Name</mat-label>
<input matInput [(ngModel)]="Items.Name">
</mat-form-field>
</div>
不知道该不该Items.Name我只是举个例子
数组看起来像这样:
import { StorageItem } from './StorageItem';
export const Items: StorageItem[] = [
{ Quantity: 11, Name: 'Sand', Unit: 'kg'},
{ Quantity: 6, Name: 'Lamps', Unit: 'pcs'},
{ Quantity: 18, Name: 'Rocks', Unit: 'kg'},
{ Quantity: 2, Name: 'Tables', Unit: 'pcs'},
{ Quantity: 2, Name: 'Water', Unit: 'l'},
{ Quantity: 200, Name: 'Rope', Unit: 'm'},
];
StorageItem 界面是这样的:
export interface StorageItem {
Name: string;
Quantity: number;
Unit: string;
}
所以我想要实现的是打开对话框 window 并输入名称,以便我可以更改它并关闭对话框。如果它仅用于会话也很好,我不需要它来更改文件。重新加载后它可以恢复为默认值。 如果我输入 data.Unit 它会起作用,但这不是我想将它绑定到项目名称并更改它的重点。 有一个 table genrated let StorageItem of Items 加上按钮所以每个对象旁边都有按钮。
我试过像在英雄之旅中所做的那样
selected: StorageItem
funcionOnclickToOpenDialog(storageItem: StorageItem){
this.selected = storageItem;
}
但这也没有用。
如果有任何遗漏或您希望我澄清,我将很乐意提供帮助。
您编辑的是名称而不是单位:)
dialogRef.afterClosed().subscribe(Unit => {
console.log('The dialog was closed');
this.Unit = Unit;
});
你应该把上面的改成这样:
dialogRef.afterClosed().subscribe(name => {
console.log('The dialog was closed');
this.Name = name;
});
项目应该是 class 变量才能在模板中使用。 我在这里看到 Items 是用 const 声明的。应该是
Items: StorageItem[] = [
{ Quantity: 11, Name: 'Sand', Unit: 'kg'},
{ Quantity: 6, Name: 'Lamps', Unit: 'pcs'},
{ Quantity: 18, Name: 'Rocks', Unit: 'kg'},
{ Quantity: 2, Name: 'Tables', Unit: 'pcs'},
{ Quantity: 2, Name: 'Water', Unit: 'l'},
{ Quantity: 200, Name: 'Rope', Unit: 'm'},
];
问题出在我的 html 中,当使用 ng-container 时,表单开始变得奇怪。 现在,当我递归地生成我的 html 时,这个解决方案有效:
<ng-template #formCategoryTemplate let-formCategory>
<div [formGroup]="getFormGroup(formCategory)" class="request-form">
</ng-container>
<tr class="input" *ngIf="isInput(formEntry)">
<td>
<mat-form-field appearance="outline" class="full-width">
<input [formControl]="getFormControl(toInput(formEntry))" matInput>
</mat-form-field>
</td>
</tr>
</ng-container>
</div>
</ng-template>
toIput 将只接受条目,return entry as InputEntry
getFormGroup 将 return myFormGroup