![](/img/trans.png)
[英]How can I dynamically create and patch the value of a select field on an Angular reactive form?
[英]How can I patch an image field in a reactive form in Angular?
我正在努力解決這個問題。 我有一個創建項目的表單,這個項目可以有一個縮略圖。 為了上傳圖片,我使用了ngx-mat-file-input
庫。 我創建上傳如下:
component.html
:
<mat-form-field>
<ngx-mat-file-input #photo formControlName="photo" placeholder="Image" (change)="onAddImage($event)"></ngx-mat-file-input>
<button mat-icon-button matSuffix *ngIf="!photo.empty" (click)="photo.clear($event); ">
<mat-icon matSuffix>clear</mat-icon>
</button>
<mat-icon matSuffix *ngIf="photo.empty">photography</mat-icon>
<mat-error *ngIf="hasError('photo', 'maxContentSize')">
The total size must not exceed {{itemForm.get('photo')?.getError('maxContentSize').maxSize | byteFormat}} ({{itemForm.get('photo')?.getError('maxContentSize').actualSize
| byteFormat}}).
</mat-error>
</mat-form-field>
<div *ngIf="!photo.empty" style="float: left; margin: 5px">
<img [src]="imageSrc" *ngIf="imageSrc" style="max-height: 100px; max-width:100x">
</div>
然后我在我的 typescript: component.ts
中有這個方法:
// properties
readonly photoMaxSize = 2*2**20; // 2MB
imageSrc: string | undefined; // Used to preview image
itemForm: FormGroup;
// constructor
this.itemForm = new FormGroup({
photo: new FormControl(undefined, [FileValidator.maxContentSize(this.photoMaxSize)]),
name: new FormControl('', [Validators.required, Validators.maxLength(100)]),
});
// validation
hasError(controlName: string, errorName: string){
return this.itemForm.controls[controlName].hasError(errorName);
}
// create thumbnail when creating the form
onAddImage(event: any) {
const reader = new FileReader();
if(event.target.files && event.target.files.length) {
const [file] = event.target.files;
reader.readAsDataURL(file);
reader.onload = () => {
this.imageSrc = reader.result as string;
this.itemForm.patchValue({
fileSource: reader.result
});
};
}
}
我的問題來了,它被發送到后端,然后作為 JSON 返回,其中包含一個 URL 到圖像,所以我開始在我的表單中創建類似這樣的東西來修補值:
patchFormOnEdit(id: number){
this.itemService.getItem(id).subscribe(
(res: Item) =>{
// Patch strings
this.itemForm.patchValue({
name: res.name,
});
// Thumbnail:
if (res.photo){
console.log("Setting thumbnail to " + res.photo);
this.imageSrc = res.photo;
this.itemForm.patchValue({
photo: res.photo,
});
}
}
);
}
但它已經崩潰了:
R TypeError: control.value.files is undefined
maxContentSize ngx-material-file-input.js:403
Angular 9
patchFormOnEdit XXXX.component.ts:140
RxJS 13
Angular 16
RxJS 18
patchFormOnEdit XXXX.component.ts:107
ngOnInit .component.ts:101
Angular 22
RxJS 5
Angular 22
ItemTableComponent_td_39_Template YYYY.component.html:129
Angular 11
RxJS 5
我的猜測是我不能 map 將 URL 轉換為圖書館使用的 object。 我該如何解決這個問題?
我的目標是與我創建的相同,我可以在其中刪除或更改項目,但使用已保存在后端的內容作為 src,而不是用戶在創建時輸入的內容:
我找到了一個解決方案,我不知道它是否是正確的方法,但至少是可行的。
我無法使用ngx-mat-file-input
來顯示我從后端獲得的圖像,我不知道它是否可能,或者它是否只處理來自用戶的本地文件。
所以我創建了一個 select 框來刪除該項目:
component.ts
:
previousImageSrc: string | undefined; // Used to store previous image
deletePreviousImage: boolean | undefined = undefined; // Delete backend image on patch
...
...
// Patch Thumbnail:
if (res.photo){
this.imageSrc=res.photo;
this.previousImageSrc=res.photo;
this.deletePreviousImage = false;
}
...
...
// Add image using the nxg-mat-file-input
onAddImage(event: any) {
const reader = new FileReader();
if(event.target.files && event.target.files.length) {
const [file] = event.target.files;
reader.readAsDataURL(file);
reader.onload = () => {
this.imageSrc = reader.result as string;
this.itemForm.patchValue({
fileSource: reader.result
});
};
this.deletePreviousImage = false;
}
}
// When the user removes an image display again what is in backend
onRemoveImage(){
if(this.previousImageSrc){
this.imageSrc = this.previousImageSrc;
this.deletePreviousImage = false;
}
}
然后更新 html 以包含此刪除映像 function:
component.html
<!-- Photo -->
<div class="row-group">
<mat-form-field>
<ngx-mat-file-input #photo formControlName="photo" placeholder="Image" (change)="onAddImage($event)"></ngx-mat-file-input>
<button mat-icon-button matSuffix *ngIf="!photo.empty" (click)="photo.clear($event); onRemoveImage()">
<mat-icon matSuffix>clear</mat-icon>
</button>
<mat-icon matSuffix *ngIf="photo.empty">photography</mat-icon>
<mat-error *ngIf="hasError('photo', 'maxContentSize')">
The total size must not exceed {{itemForm.get('photo')?.getError('maxContentSize').maxSize | byteFormat}} ({{itemForm.get('photo')?.getError('maxContentSize').actualSize
| byteFormat}}).
</mat-error>
</mat-form-field>
<div *ngIf="imageSrc" style="float: left; margin: 5px">
<!-- Display Preview -->
<img [src]="imageSrc" alt='Item image' *ngIf="imageSrc" style="max-height: 100px; max-width:100x">
<!-- deletePreviousImage -->
<div *ngIf="deletePreviousImage !== undefined && photo.empty">
<br>
<mat-checkbox
class="checkbox"
formControlName="deletePreviousImage"
id="item:edit:deletePreviousImage"
>
Delete image
</mat-checkbox>
</div>
</div>
</div>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.