6

我正在阅读Max NgWizard K 的一篇文章,关于 Angular 如何更新 DOM。我遇到了以下情况:

对于应用程序中使用的每个组件,Angular 编译器都会生成一个工厂。当 Angular 从工厂创建组件时,Angular 使用这个工厂来实例化视图定义,而视图定义又用于创建组件视图。在引擎盖下,Angular 将应用程序表示为视图树。

在Max NgWizard KI 的另一篇文章中,找到了工厂的定义:

工厂描述组件视图的结构,并在实例化组件时使用。

我不太确定这是什么意思。

问题:

  1. Angular(2+)中的工厂到底是什么?
  2. 是否存在开发人员从了解其工作方式中受益的场景?
4

3 回答 3

7

Angular(2+)中的工厂到底是什么?

工厂是四人帮提到的设计模式之一(基本上他们写了一本关于他们发现的设计模式的书)。

设计模式帮助程序员以特定的方式解决常见的开发任务。

在这种情况下,工厂模式有助于实例化和创建对象。

它也被称为虚拟构造函数。


想一想,像这样:

假设您正在制作 2D 射击游戏,并且您必须从枪管中射出子弹。

new Bullet()每次扣动扳机时,您都可以使用工厂来创建子弹,而不是实例化子弹,即WeaponsFactory.createInstance(BulletTypes.AK47_BULLET).

它变得高度可扩展,因为您所要做的就是更改枚举,工厂将为您制作。

您不必手动实例化它。


这就是 Angular 所做的,它会自动创建所有组件的工厂。这使得它的工作更容易。

是否存在开发人员从了解其工作方式中受益的场景?

您不必了解工厂的内部工作原理即可使用 Angular,但它对于动态创建组件很有用!

例如,很多*ngIf,或*ngSwitchCase可以用简单的动态生成组件来代替

组件可以像这样动态创建:

createComponent(type) {
  this.container.clear();
  const factory: ComponentFactory = this.resolver.resolveComponentFactory(AlertComponent);
  this.componentRef: ComponentRef = this.container.createComponent(factory);
}

理解上述代码的参考:动态创建组件

于 2018-03-05T17:33:11.673 回答
1

在这种情况下,“工厂”是 的实例ComponentFactory,该类具有create实现工厂方法模式的方法。

componentFactory.create被调用时(直接或通过- 正如链接文章ComponentFactoryResolver所解释的那样,这对于动态组件至关重要),会创建新的组件实例。

于 2018-03-05T17:37:03.447 回答
0

一般来说,工厂是一种创造设计模式。它是一个用于创建其他对象的对象——从形式上讲,工厂是一个函数或方法,它从某个方法调用返回不同原型或类的对象。

来自Angular 文档

@Component({
  selector: 'app-typical',
  template: '<div>A typical component for {{data.name}}</div>'
)}
export class TypicalComponent {
  @Input() data: TypicalData;
  constructor(private someService: SomeService) { ... }
}

Angular 编译器提取一次元数据并为典型组件生成一个工厂。当它需要创建一个TypicalComponent 实例时,Angular 会调用工厂,它会生成一个新的可视元素,并绑定到具有注入依赖项的组件类的新实例。

这是幕后发生的事情。但是您也可以使用 ComponentFactoryResolver 创建动态组件(动态组件加载器

//Only dynamic component creation logic is shown below
loadComponent() {
    this.currentAdIndex = (this.currentAdIndex + 1) % this.ads.length;
    const adItem = this.ads[this.currentAdIndex];

    const componentFactory = this.componentFactoryResolver.resolveComponentFactory(adItem.component);

    const viewContainerRef = this.adHost.viewContainerRef;
    viewContainerRef.clear();

    const componentRef = viewContainerRef.createComponent<AdComponent>(componentFactory);
    componentRef.instance.data = adItem.data;
}

另请阅读这篇关于组件工厂如何在 Ivy中工作的文章。

于 2020-08-29T06:22:15.350 回答