在角度模块中使用注入的故事书

时间:2019-07-03 10:47:15

标签: angular storybook

我想使用Storybook开发和测试我的UI组件,并将它们作为npm库从同一项目中发布。这就是为什么我将所有组件封装为单个功能模块的原因。我想创建一个简单的模块,该模块生成一个表单并允许某些撤消功能。我的问题是Storybook无法将Formbuilder服务注入到我的组件中。

我的设置如下:

故事:

storiesOf('UndoForm', module)
  .addDecorator(
    moduleMetadata({
      imports: [ReactiveFormsModule, UndoFormModule]
    }),
  )
  .add('Testform', () => ({
    template: '<mods-undo-form></mods-undo-form>'
  })
);

UndoFormModule:

@NgModule({
  declarations: [UndoFormComponent],
  imports: [ReactiveFormsModule],
  exports: [UndoFormComponent]
})
export class UndoFormModule {}

UndoFormComponent:

@Component({
  selector: 'mods-undo-form',
  templateUrl: './undo-form.component.html',
  styleUrls: ['./undo-form.component.scss']
})
export class UndoFormComponent implements OnInit {
  [...]
  constructor(private fb: FormBuilder) { }
  [...]
}

我得到的错误是:

  

无法解析UndoFormComponent的所有参数:(?)。

我发现的是,当我显式使用@Inject批注时,代码可以正常工作

constructor(@Inject(FormBuilder) private fb: FormBuilder) { }

是否有可能阻止使用显式注释?

3 个答案:

答案 0 :(得分:0)

您需要在故事书装饰器的moduleMetadata的providers数组中提供“ FormBuilder”。这样,您的故事书设置将识别FormBuilder被用作组件中的可注入依赖项。

这是我在我们的故事之一中使用它的方式:

storiesOf('UndoForm', module)
  .addDecorator(
    moduleMetadata({
      imports: [ReactiveFormsModule, UndoFormModule],
      providers: [FormBuilder],
    }),
  )
  .add('Testform', () => ({
    template: '<mods-undo-form></mods-undo-form>'
  })
);

答案 1 :(得分:0)

您需要在"emitDecoratorMetadata": true文件的compilerOptions对象中添加.storybook/tsconfig.json

所以您的.storybook/tsconfig.json应该是这样的:

{
  "extends": "../tsconfig.app.json",
  "compilerOptions": {
    "emitDecoratorMetadata": true,   <--------- Add this!
    ...
  },
  ...
}

然后确保重新启动故事书过程。

答案 2 :(得分:0)

您可以将其直接导入故事中。像这样:

import { BannerV2Component } from './banner.v2.component';
import { moduleMetadata } from '@storybook/angular';


export default { 
  title: 'Banner',
  decorators: [
    moduleMetadata({
        imports: [ReactiveFormsModule, UndoFormModule],
        providers: [FormBuilder],
    })
  ]
}
export const OptionOne = () => ({
  component: BannerV2Component,
  props: {
    mainText:'Text Two',
    showBreadcrumbs:true,
  },
});