Angular 14: 实现工厂模式

huangapple go评论59阅读模式
英文:

Angular 14: Implement Factory pattern

问题

我想在Angular中实现工厂模式

重点是,我需要创建多个表单,但每个表单都有自己的属性,所以我认为最好的方法是创建一个表单工厂,根据类型,工厂将呈现一个表单或另一个表单。

app.component.html

<app-form-builder [type]="'phoneForm'"></app-form-builder>

form-builder.component.ts

interface FormMapping {
  [key: string]: ComponentRef<FormNameComponent | FormPhoneComponent>;
}

@Input() type: string = '';

constructor(public viewContainerRef: ViewContainerRef) {}

getFormTypes(type: string) {
  const formMapping: FormMapping = {
    nameForm: this.viewContainerRef.createComponent(FormNameComponent),
    phoneForm: this.viewContainerRef.createComponent(FormPhoneComponent),
  };

  formMapping[type];
}

ngOnInit(): void {
  this.getFormTypes(this.type);
}

表单组件不重要,因为phoneForm显示一个带有input type number的表单,而nameForm显示一个带有input type text的表单。

如果使用多个if语句,这种方法可以正常工作,但如果使用对象,它会同时呈现两个表单,我不知道为什么会这样。

getFormType(type: string) {
  if (type === 'nameForm') {
    this.viewContainerRef.createComponent(FormNameComponent);
  }

  if (type === 'phoneForm') {
    this.viewContainerRef.createComponent(FormPhoneComponent);
  }
}

在StackBlitz上查看演示

我已经遵循了这个StackOverflow问题,但这个示例显示了如何实例化一个Service,而在我的情况下,我想要实例化一个组件

英文:

I want to implement Factory pattern in Angular.

The point is, I need to create several forms but every form has its owns properties so I thought the best approach was to create a Factory of forms and depends of the type the factory will render one form or another.

app.component.html

&lt;app-form-builder [type]=&quot;&#39;phoneForm&#39;&quot;&gt;&lt;/app-form-builder&gt;

form-builder.component.ts

interface FormMapping {
  [key: string]: ComponentRef&lt;FormNameComponent | FormPhoneComponent&gt;;
}

@Input() type: string = &#39;&#39;;

constructor(public viewContainerRef: ViewContainerRef) {}

getFormTypes(type: string) {
  const formMapping: FormMapping = {
    nameForm: this.viewContainerRef.createComponent(FormNameComponent),
    phoneForm: this.viewContainerRef.createComponent(FormPhoneComponent),
  };

  formMapping[type];
}

ngOnInit(): void {
  this.getFormTypes(this.type);
}

The form components are not relevant since the phoneForm displays a form with a input type number and the nameForm displays a form with a input type text.

The approach works if I use multiple If's but I don't know why don't if I use the object because it renders the two forms at the same time.

getFormType(type: string) {
  if (type === &#39;nameForm&#39;) {
    this.viewContainerRef.createComponent(FormNameComponent);
  }

  if (type === &#39;phoneForm&#39;) {
    this.viewContainerRef.createComponent(FormPhoneComponent);
  }
}

Demo @ StackBlitz

I have followed this StackOverflow question but this example shows how to instantiate a Service but in my case I want to instantiate a component.

答案1

得分: 1

你的问题出现在映射创建部分:

const formMapping: FormMapping = {
     nameForm: this.viewContainerRef.createComponent(FormNameComponent),
     phoneForm: this.viewContainerRef.createComponent(FormPhoneComponent),
};

当你创建映射时,实际上也在调用 "createComponent" 实例化组件。

你应该像这样创建映射:

const formMapping: FormMapping = {
     nameForm: FormNameComponent,
     phoneForm: FormPhoneComponent,
};

然后根据值调用 "create":

this.viewContainerRef.createComponent(getFormTypes('...'));
英文:

your problem resides in the mapping creation part:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

 const formMapping: FormMapping = {
      nameForm: this.viewContainerRef.createComponent(FormNameComponent),
      phoneForm: this.viewContainerRef.createComponent(FormPhoneComponent),
    };

<!-- end snippet -->

When you are creating mapping basically are you instantiating also teh components by calling "createComponent".

You should create mapping like this:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

 const formMapping: FormMapping = {
      nameForm: FormNameComponent,
      phoneForm: FormPhoneComponent,
    };

<!-- end snippet -->

End just call create based on the value:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

 this.viewContainerRef.createComponent(getFormTypes(&#39;...&#39;));

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年2月10日 14:49:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/75407764.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定