You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为自定义Formly字段编写Storybook故事?

为Angular Formly自定义文件字段编写Storybook故事

要在Storybook中预览你的自定义Formly文件字段,需要在故事中搭建Formly表单的运行环境,以下是具体实现步骤:

1. 创建Storybook专用宿主组件

在字段组件目录下创建临时宿主组件,模拟Formly表单的运行环境:

// formly-file-field.story-host.component.ts
import { Component } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { FormlyFormOptions, FormlyFieldConfig } from '@ngx-formly/core';

@Component({
  template: `
    <form [formGroup]="form" class="p-4">
      <formly-form 
        [model]="model" 
        [fields]="fields" 
        [options]="options" 
        [form]="form">
      </formly-form>
    </form>
  `,
})
export class FormlyFileFieldStoryHostComponent {
  form = new FormGroup({});
  model: Record<string, any> = {};
  options: FormlyFormOptions = {};
  fields: FormlyFieldConfig[] = [
    {
      key: 'testFile',
      type: 'file',
      props: {
        label: '选择文件',
        placeholder: '点击上传文件',
      },
    },
  ];
}

2. 编写Storybook故事文件

创建对应的.stories.ts文件,配置模块导入并定义故事:

// formly-file-field.component.stories.ts
import { Meta, Story } from '@storybook/angular';
import { FormlyFileFieldComponent } from './formly-file-field.component';
import { FormlyFileFieldStoryHostComponent } from './formly-file-field.story-host.component';
import { ReactiveFormsModule } from '@angular/forms';
import { FormlyModule } from '@ngx-formly/core';
import { FileValueAccessor } from './file-value-accessor';

export default {
  title: 'Formly/File Field',
  component: FormlyFileFieldStoryHostComponent,
  decorators: [
    (story) => ({
      moduleMetadata: {
        imports: [
          ReactiveFormsModule,
          FormlyModule.forRoot({
            types: [
              { name: 'file', component: FormlyFileFieldComponent },
            ],
          }),
        ],
        declarations: [
          FormlyFileFieldComponent,
          FormlyFileFieldStoryHostComponent,
          FileValueAccessor,
        ],
      },
    }),
  ],
} as Meta;

const Template: Story<FormlyFileFieldStoryHostComponent> = (args) => ({
  props: args,
});

export const Basic = Template.bind({});
Basic.args = {};

// 扩展多文件上传场景示例
export const MultipleFiles = Template.bind({});
MultipleFiles.args = {};
MultipleFiles.decorators = [
  (story) => ({
    template: `
      <form [formGroup]="form" class="p-4">
        <formly-form 
          [model]="model" 
          [fields]="[{
            key: 'testFiles',
            type: 'file',
            props: {
              label: '选择多个文件',
              multiple: true,
              accept: '.pdf,.docx',
            },
          }]" 
          [options]="options" 
          [form]="form">
        </formly-form>
      </form>
    `,
  }),
];

关键注意事项

  • 必须在FormlyModule.forRoot中注册自定义file字段类型,确保Formly能识别并渲染该字段。
  • 需导入ReactiveFormsModule、FormlyModule,同时声明FileValueAccessor指令,否则文件输入框无法与表单控件正常绑定。
  • 宿主组件用于模拟真实项目中Formly表单的运行环境,可按需调整字段的props配置(如添加标签、限制文件类型、开启多文件上传等),覆盖不同使用场景。

内容的提问来源于stack exchange,提问作者Philipp Doerner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 20:04:55