Angular FormArray 没有像我预期的那样工作
Angular FormArray not working as I expect
我希望你能帮我解决这个问题。
我有一个允许我动态添加项目到数组的表单,如果我们正在编辑并且看起来像这样,可以预先填充数组:
<mat-list class="hall-list"
*ngIf="f.halls.length">
<mat-list-item *ngFor="let hall of f.halls.controls;">
<ng-container [formGroup]="hall">
<img [src]="hall.url"
matListAvatar />
<p matLine>{{ hall.url }}</p>
<p matLine>{{ hall.startTime }}</p>
<p matLine>
<mat-form-field class="full-width-field">
<mat-label for="url">Start time *</mat-label>
<input matInput
placeholder="Enter the start time"
formControlName="startTime">
</mat-form-field>
</p>
</ng-container>
</mat-list-item>
</mat-list>
如您所见,我正在尝试显示基于 "hall" 的 url 的图像。
我已将其设置如下:
ngOnInit() {
this.buildForm();
this.getHall();
}
get f() {
return this.form.controls;
}
private buildForm(): void {
this.form = this.formBuilder.group({
videoUrl: ["", Validators.required],
tags: ["", Validators.required],
halls: this.formBuilder.array([])
});
}
private getHall(): void {
this.querySubscription = this.route.queryParams.subscribe(params => {
const id = params.hallId || 0;
const halls = this.form.controls.halls as FormArray;
if (id) {
this.hallService.get(id, "Videos").subscribe(hall => {
const group = new FormGroup({
id: new FormControl(hall.id),
url: new FormControl(hall.url, Validators.required),
startTime: new FormControl("", Validators.required)
});
halls.push(group);
});
}
});
}
但是当我查看我的页面时,虽然没有出现任何错误,但它不显示图像。我添加了 <p matLine>
来尝试调试,但它们也是空的。
有谁知道我做错了什么?
只是因为有些人在陈述错误,这里是总的 html 文件:
<form [formGroup]="form"
(ngSubmit)="save(form.value)"
novalidate>
<app-stepper #stepper>
<app-step name="Video"
[expanded]="stepper.step === 0">
<mat-form-field class="full-width-field">
<mat-label for="videoUrl">Youtube link *</mat-label>
<input matInput
placeholder="Enter a valid image url"
formControlName="videoUrl">
</mat-form-field>
<app-tags (change)="onChangeTags($event)"></app-tags>
<mat-action-row>
<button mat-raised-button
type="button"
color="primary"
(click)="getSnippet()"
[disabled]="!f.videoUrl.valid || !f.tags.valid">Next</button>
</mat-action-row>
</app-step>
<app-step name="Halls"
[expanded]="stepper.step === 1"
[disabled]="stepper.step < 1">
<p>Chanell: {{ model?.channelTitle }}</p>
<p>Title: {{ model?.title }}</p>
<mat-list class="hall-list"
*ngIf="f.halls.length">
<div formArrayName="halls">
<mat-list-item *ngFor="let hall of f.halls.controls;">
<ng-container [formGroup]="hall">
<img [src]="hall.url"
matListAvatar />
<p matLine>{{ hall.url }}</p>
<p matLine>{{ hall.startTime }}</p>
<p matLine>
<mat-form-field class="full-width-field">
<mat-label for="url">Start time *</mat-label>
<input matInput
placeholder="Enter the start time"
formControlName="startTime">
</mat-form-field>
</p>
</ng-container>
</mat-list-item>
</div>
</mat-list>
<app-image-previewer [files]="files"
[urls]="urls"
[progress]="progress"></app-image-previewer>
<mat-action-row>
<app-file [files]="files"
[urls]="urls"></app-file>
<button mat-raised-button
type="submit"
color="primary"
[disabled]="!form.valid || !f.halls.length">Save</button>
</mat-action-row>
</app-step>
</app-stepper>
</form>
这是一个显示问题的 stackblitz:https://angular6-dynamic-form-array-vnnye9.stackblitz.io
你应该使用 formArrayName
<mat-list class="hall-list"
*ngIf="f.halls.length">
<div formArrayName="halls">
<mat-list-item *ngFor="let hall of f.halls.controls;">
<ng-container [formGroup]="hall">
<img [src]="hall.url"
matListAvatar />
<p matLine>{{ hall.url }}</p>
<p matLine>{{ hall.startTime }}</p>
<p matLine>
<mat-form-field class="full-width-field">
<mat-label for="url">Start time *</mat-label>
<input matInput
placeholder="Enter the start time"
formControlName="startTime">
</mat-form-field>
</p>
</ng-container>
</div>
</mat-list-item>
</mat-list>
可能出现的问题:
- hall.url 应该是 hall.value.url.
- formArrayName下的[formGroup]应该是循环的索引f.halls.controls。
在您的 html 文件中:
<mat-list class="hall-list" *ngIf="f.halls.length">
<div formArrayName="halls">
<mat-list-item *ngFor="let hall of f.halls.controls; index as i">
<ng-container [formGroup]="i">
<img [src]="hall.value.url"
matListAvatar />
<p matLine>{{ hall.value.url }}</p>
<p matLine>{{ hall.value.startTime }}</p>
<p matLine>
<mat-form-field class="full-width-field">
<mat-label for="url">Start time *</mat-label>
<input matInput
placeholder="Enter the start time"
formControlName="startTime">
</mat-form-field>
</p>
</ng-container>
</mat-list-item>
</div>
</mat-list>
参考您提供的最新stackblitz代码,图像src
的值为空,您可以使用从表单组到数组级别的引用以及每个索引设置该值,如myForm.value.arr[i].url
..
因此
改变,
<div><img [src]="url" alt="some url" /></div>
收件人:
<div><img [src]="myForm.value.arr[i].url" alt="some url" /></div>
更改原因:
您正在迭代一个数组以显示 url
,它没有任何值,因此它给出 null..
大家可以看看下图,
这里通常用于检索我们使用的表单值,{{myForm.value | json}}
将给出表单值的 json 格式,因此使用它您需要找出 url 的确切位置谎言,那么你就可以找到路径。
所以在你的情况下它可以在这里 myForm.value.arr[i].url
.. 我们需要从表单级对象访问它到索引数组然后是该项目的 url。
我希望你能帮我解决这个问题。 我有一个允许我动态添加项目到数组的表单,如果我们正在编辑并且看起来像这样,可以预先填充数组:
<mat-list class="hall-list"
*ngIf="f.halls.length">
<mat-list-item *ngFor="let hall of f.halls.controls;">
<ng-container [formGroup]="hall">
<img [src]="hall.url"
matListAvatar />
<p matLine>{{ hall.url }}</p>
<p matLine>{{ hall.startTime }}</p>
<p matLine>
<mat-form-field class="full-width-field">
<mat-label for="url">Start time *</mat-label>
<input matInput
placeholder="Enter the start time"
formControlName="startTime">
</mat-form-field>
</p>
</ng-container>
</mat-list-item>
</mat-list>
如您所见,我正在尝试显示基于 "hall" 的 url 的图像。 我已将其设置如下:
ngOnInit() {
this.buildForm();
this.getHall();
}
get f() {
return this.form.controls;
}
private buildForm(): void {
this.form = this.formBuilder.group({
videoUrl: ["", Validators.required],
tags: ["", Validators.required],
halls: this.formBuilder.array([])
});
}
private getHall(): void {
this.querySubscription = this.route.queryParams.subscribe(params => {
const id = params.hallId || 0;
const halls = this.form.controls.halls as FormArray;
if (id) {
this.hallService.get(id, "Videos").subscribe(hall => {
const group = new FormGroup({
id: new FormControl(hall.id),
url: new FormControl(hall.url, Validators.required),
startTime: new FormControl("", Validators.required)
});
halls.push(group);
});
}
});
}
但是当我查看我的页面时,虽然没有出现任何错误,但它不显示图像。我添加了 <p matLine>
来尝试调试,但它们也是空的。
有谁知道我做错了什么?
只是因为有些人在陈述错误,这里是总的 html 文件:
<form [formGroup]="form"
(ngSubmit)="save(form.value)"
novalidate>
<app-stepper #stepper>
<app-step name="Video"
[expanded]="stepper.step === 0">
<mat-form-field class="full-width-field">
<mat-label for="videoUrl">Youtube link *</mat-label>
<input matInput
placeholder="Enter a valid image url"
formControlName="videoUrl">
</mat-form-field>
<app-tags (change)="onChangeTags($event)"></app-tags>
<mat-action-row>
<button mat-raised-button
type="button"
color="primary"
(click)="getSnippet()"
[disabled]="!f.videoUrl.valid || !f.tags.valid">Next</button>
</mat-action-row>
</app-step>
<app-step name="Halls"
[expanded]="stepper.step === 1"
[disabled]="stepper.step < 1">
<p>Chanell: {{ model?.channelTitle }}</p>
<p>Title: {{ model?.title }}</p>
<mat-list class="hall-list"
*ngIf="f.halls.length">
<div formArrayName="halls">
<mat-list-item *ngFor="let hall of f.halls.controls;">
<ng-container [formGroup]="hall">
<img [src]="hall.url"
matListAvatar />
<p matLine>{{ hall.url }}</p>
<p matLine>{{ hall.startTime }}</p>
<p matLine>
<mat-form-field class="full-width-field">
<mat-label for="url">Start time *</mat-label>
<input matInput
placeholder="Enter the start time"
formControlName="startTime">
</mat-form-field>
</p>
</ng-container>
</mat-list-item>
</div>
</mat-list>
<app-image-previewer [files]="files"
[urls]="urls"
[progress]="progress"></app-image-previewer>
<mat-action-row>
<app-file [files]="files"
[urls]="urls"></app-file>
<button mat-raised-button
type="submit"
color="primary"
[disabled]="!form.valid || !f.halls.length">Save</button>
</mat-action-row>
</app-step>
</app-stepper>
</form>
这是一个显示问题的 stackblitz:https://angular6-dynamic-form-array-vnnye9.stackblitz.io
你应该使用 formArrayName
<mat-list class="hall-list"
*ngIf="f.halls.length">
<div formArrayName="halls">
<mat-list-item *ngFor="let hall of f.halls.controls;">
<ng-container [formGroup]="hall">
<img [src]="hall.url"
matListAvatar />
<p matLine>{{ hall.url }}</p>
<p matLine>{{ hall.startTime }}</p>
<p matLine>
<mat-form-field class="full-width-field">
<mat-label for="url">Start time *</mat-label>
<input matInput
placeholder="Enter the start time"
formControlName="startTime">
</mat-form-field>
</p>
</ng-container>
</div>
</mat-list-item>
</mat-list>
可能出现的问题:
- hall.url 应该是 hall.value.url.
- formArrayName下的[formGroup]应该是循环的索引f.halls.controls。
在您的 html 文件中:
<mat-list class="hall-list" *ngIf="f.halls.length">
<div formArrayName="halls">
<mat-list-item *ngFor="let hall of f.halls.controls; index as i">
<ng-container [formGroup]="i">
<img [src]="hall.value.url"
matListAvatar />
<p matLine>{{ hall.value.url }}</p>
<p matLine>{{ hall.value.startTime }}</p>
<p matLine>
<mat-form-field class="full-width-field">
<mat-label for="url">Start time *</mat-label>
<input matInput
placeholder="Enter the start time"
formControlName="startTime">
</mat-form-field>
</p>
</ng-container>
</mat-list-item>
</div>
</mat-list>
参考您提供的最新stackblitz代码,图像src
的值为空,您可以使用从表单组到数组级别的引用以及每个索引设置该值,如myForm.value.arr[i].url
..
因此
改变,
<div><img [src]="url" alt="some url" /></div>
收件人:
<div><img [src]="myForm.value.arr[i].url" alt="some url" /></div>
更改原因:
您正在迭代一个数组以显示 url
,它没有任何值,因此它给出 null..
大家可以看看下图,
这里通常用于检索我们使用的表单值,{{myForm.value | json}}
将给出表单值的 json 格式,因此使用它您需要找出 url 的确切位置谎言,那么你就可以找到路径。
所以在你的情况下它可以在这里 myForm.value.arr[i].url
.. 我们需要从表单级对象访问它到索引数组然后是该项目的 url。