发生该错误是因为您设置了方法 save() 来获取 console.log。当您使用
customUpload
并且您想通过单击按钮获取文件时,您可以使用 Angular 中的 @ViewChild
方法。查看代码,您将了解它是如何工作的。
首先给你的
fileUpload
一个像#fileUpload
这样的id,你不需要在这里设置formControlName
。相反,您可以在 new FormControl
中设置 formBuilder group
。
<form [formGroup]="form">
<p-fileUpload
#fileUpload
[customUpload]="true"
(uploadHandler)="uploadFile($event)"
></p-fileUpload>
</form>
<button (click)="save()">save</button>
然后在您的
.ts
文件中,您必须导入 @ViewChild
方法并查看 FileUpload。
在 uploadFile
事件中我们可以获取文件并使用 patchValue
方法我们可以设置表单字段的值。
export class AppComponent implements OnInit {
@ViewChild('fileUpload') fileUpload: FileUpload;
form: FormGroup;
constructor(private fb: FormBuilder) {}
ngOnInit() {
this.form = this.fb.group({
myFile: new FormControl(),
});
}
uploadFile(event) {
for (let file of event.files) {
this.form.patchValue({ myFile: file });
this.form.get('myFile').updateValueAndValidity();
}
}
save(){
this.fileUpload.upload();
console.log(this.form.value.myFile)
}
}
演示:stackblitz
您可以创建自定义
ControlValueAccessor
指令,以便自动将上传的文件绑定到表单控件。
模板:
<p-fileUpload formControlName="abcFile"></p-fileUpload>
指令:
import { Directive, forwardRef } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { FileUpload } from 'primeng/fileupload';
@Directive({
selector: 'p-fileUpload[formControlName], p-fileUpload[formControl]',
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => FileUploadControlValueAccessorDirective),
multi: true,
},
],
})
export class FileUploadControlValueAccessorDirective
implements ControlValueAccessor
{
constructor(private fileUpload: FileUpload) {}
writeValue(value: any): void {
// update the model and changes logic goes here
}
registerOnChange(fn: any): void {
// notify the outside world about changes (when the user interacts with the input)
this.fileUpload.onUpload.subscribe(fn);
}
registerOnTouched(fn: any): void {
// here goes the touch logic
this.fileUpload.onClear.subscribe(fn);
}
setDisabledState(isDisabled: boolean) {
this.fileUpload.disabled = isDisabled;
}
}
我无法真正让 Meqwz 解决方案发挥作用,但它启发了我这个解决方案:
export class FileUploadControlValueAccessorDirective implements ControlValueAccessor, OnDestroy {
#fileUpload = inject(FileUpload);
#ngUnsubscribe = new Subject<void>();
writeValue(_: File[]): void {
// this handles the use of form.reset()
if (!files.length) {
this.#fileUpload.clear();
}
}
registerOnChange(fn: any): void {
this.#fileUpload.uploadHandler.pipe(
map(event => event.files),
takeUntil(this.#ngUnsubscribe)
).subscribe(files => fn(files));
this.#fileUpload.onRemove.pipe(
takeUntil(this.#ngUnsubscribe)
).subscribe(() => fn(this.#fileUpload.files));
}
registerOnTouched(_fn: never): void {
// nothing to do
}
setDisabledState(isDisabled: boolean) {
this.#fileUpload.disabled = isDisabled;
}
ngOnDestroy(): void {
this.#ngUnsubscribe.next();
this.#ngUnsubscribe.complete();
}
}
我获得了
FileUpload
指令所在的 formControlName
组件,并且订阅了我需要的不同事件。
试试这个
<form [formGroup]="form" >
...
<p-fileUpload [customUpload]="true" name="file-upload" (uploadHandler)="uploadFile($event)" [multiple]="false" formControlName="myFile"></p-fileUpload>
你的表格组应该是
form: FormGroup = new FormGroup({});
...
this.form = this.fb.group({
...
myFile: new FormControl(''),
});
save(){
...
const myObject = this.form.value;
...
console.log("file:", myObject.myFile) // do not use + operator, because it converts object to string as [Object Object] and it causes the confusion.
希望这有帮助:)