如何将 PrimeNG 文件上传组件绑定到我的 Angular 表单控件?

问题描述 投票:0回答:4
angular file-upload primeng angular13 form-control
4个回答
1
投票

发生该错误是因为您设置了方法 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


0
投票

您可以创建自定义

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;
  }
}

🌮Stackblitz在这里🌮


0
投票

我无法真正让 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
组件,并且订阅了我需要的不同事件。


-1
投票

试试这个

<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.

希望这有帮助:)

© www.soinside.com 2019 - 2024. All rights reserved.