IE:使用 formly 添加 FormData polyfill 到 angular
IE: Add FormData polyfill to angular with formly
我在 angular 项目中使用 https://www.npmjs.com/package/formdata-polyfill 和 nxg formly,我的表单有一个配置为 formly 的文件上传字段。现在我们必须支持 IE,并且需要一个 polyfill 才能让它工作,但我不知道如何添加它。错误是IE不支持FormData.get,需要polyfill。
polyfills.ts
...
import 'formdata-polyfill';
form.component.ts
...
this.fields = [
{
key: 'file',
id: 'field_import_file',
type: 'file-upload',
templateOptions: {
required: true,
fieldName: 'Import File',
floatLabel: 'always',
appearance: 'outline'
},
validation: {
validators: ['file-upload']
}
}
];
formdata-polyfill
应导入 polyfills.ts
文件以便在应用程序之前加载。
/***************************************************************************************************
* BROWSER POLYFILLS
*/
...
import 'formdata-polyfill';
要提交文件,您需要在表单触发提交事件后根据提交的模型构建一个 Formdata
实例。
export class AppComponent {
...
onSubmit(model) {
const formData: FormData = new FormData();
formData.append('file', model.file);
formData.append('firstname', model.firstname);
...
// send
this.http.post(url, formData) ...
}
}
没有看到任何好的解决方案,但我确实做了一个解决方法,贴在下面以防其他人遇到这个问题。请注意,这是一种解决方法,而不是正确的解决方案。
在这种情况下,我在页面上制作了一个隐藏表单,并以形式创建了一个假文件上传字段,以模拟隐藏表单上传字段的事件。
假-upload.component.ts
import { Component } from '@angular/core';
import { FieldType } from '@ngx-formly/material';
import { CustomTemplateOptions } from '../../../../../../kup-core/src/lib/models';
@Component({
selector: 'app-fake-upload-field',
template: `
<div>
<button
(click)="onClick()"
[id]="id"
type="file"
[formControl]="formControl"
[formlyAttributes]="field"
(change)="onChange()"
ngDefaultControl
[name]="id"
mat-stroked-button
>
Choose File
</button>
<input
type="text"
[value]="to.data.filename"
class="fake-file-upload-input"
(change)="onChange()"
/>
</div>
`,
styles: [
`
.fake-file-upload-input {
padding: 0;
margin: 0;
border: none;
}
`
]
})
export class FakeUploadComponent extends FieldType {
to: CustomTemplateOptions;
onClick() {
document.getElementById('realFileUpload').click();
}
onChange() {}
}
然后手动将文件值添加回表单模型,
然后隐藏表单提交按钮创建了一个伪造的表单提交面板,它模拟了事件和表单验证的老式方式。
onHiddenFileUploadChange($event) {
const el: any = document.querySelector('.fake-file-upload-input');
this.stagedFile = $event.target.files;
this.stagedFilename = $event.target.files[0].name;
el.value = this.stagedFilename;
this.checkForm();
}
triggerSave() {
const form: HTMLElement = document.getElementById('importForm');
const button: HTMLElement = form.querySelector('button[type=submit]');
button.click();
}
private onImportTypeChanged(value: FormlyFieldConfig[]): void {
this.viewModel.importTypes.map(type => {
if (type.name === value[0].formControl.value) {
value[1].formControl.patchValue(type.description);
this.stagedType = type.name;
} else if (!value[0].formControl.value) {
this.stagedType = '';
}
});
}
这是我能找到的解决 formly 缺乏遗留问题的唯一方法,即无需分叉 formly 并直接对其进行自定义即可。
我在 angular 项目中使用 https://www.npmjs.com/package/formdata-polyfill 和 nxg formly,我的表单有一个配置为 formly 的文件上传字段。现在我们必须支持 IE,并且需要一个 polyfill 才能让它工作,但我不知道如何添加它。错误是IE不支持FormData.get,需要polyfill。
polyfills.ts
...
import 'formdata-polyfill';
form.component.ts
...
this.fields = [
{
key: 'file',
id: 'field_import_file',
type: 'file-upload',
templateOptions: {
required: true,
fieldName: 'Import File',
floatLabel: 'always',
appearance: 'outline'
},
validation: {
validators: ['file-upload']
}
}
];
formdata-polyfill
应导入 polyfills.ts
文件以便在应用程序之前加载。
/***************************************************************************************************
* BROWSER POLYFILLS
*/
...
import 'formdata-polyfill';
要提交文件,您需要在表单触发提交事件后根据提交的模型构建一个 Formdata
实例。
export class AppComponent {
...
onSubmit(model) {
const formData: FormData = new FormData();
formData.append('file', model.file);
formData.append('firstname', model.firstname);
...
// send
this.http.post(url, formData) ...
}
}
没有看到任何好的解决方案,但我确实做了一个解决方法,贴在下面以防其他人遇到这个问题。请注意,这是一种解决方法,而不是正确的解决方案。
在这种情况下,我在页面上制作了一个隐藏表单,并以形式创建了一个假文件上传字段,以模拟隐藏表单上传字段的事件。
假-upload.component.ts
import { Component } from '@angular/core';
import { FieldType } from '@ngx-formly/material';
import { CustomTemplateOptions } from '../../../../../../kup-core/src/lib/models';
@Component({
selector: 'app-fake-upload-field',
template: `
<div>
<button
(click)="onClick()"
[id]="id"
type="file"
[formControl]="formControl"
[formlyAttributes]="field"
(change)="onChange()"
ngDefaultControl
[name]="id"
mat-stroked-button
>
Choose File
</button>
<input
type="text"
[value]="to.data.filename"
class="fake-file-upload-input"
(change)="onChange()"
/>
</div>
`,
styles: [
`
.fake-file-upload-input {
padding: 0;
margin: 0;
border: none;
}
`
]
})
export class FakeUploadComponent extends FieldType {
to: CustomTemplateOptions;
onClick() {
document.getElementById('realFileUpload').click();
}
onChange() {}
}
然后手动将文件值添加回表单模型,
然后隐藏表单提交按钮创建了一个伪造的表单提交面板,它模拟了事件和表单验证的老式方式。
onHiddenFileUploadChange($event) {
const el: any = document.querySelector('.fake-file-upload-input');
this.stagedFile = $event.target.files;
this.stagedFilename = $event.target.files[0].name;
el.value = this.stagedFilename;
this.checkForm();
}
triggerSave() {
const form: HTMLElement = document.getElementById('importForm');
const button: HTMLElement = form.querySelector('button[type=submit]');
button.click();
}
private onImportTypeChanged(value: FormlyFieldConfig[]): void {
this.viewModel.importTypes.map(type => {
if (type.name === value[0].formControl.value) {
value[1].formControl.patchValue(type.description);
this.stagedType = type.name;
} else if (!value[0].formControl.value) {
this.stagedType = '';
}
});
}
这是我能找到的解决 formly 缺乏遗留问题的唯一方法,即无需分叉 formly 并直接对其进行自定义即可。