Angular 中的工厂是什么

What is a factory in Angular

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

For each component that is used in the application Angular compiler generates a factory. When Angular creates a component from a factory Angular uses this factory to instantiate View Definition which in turn is used to create component View. Under the hood Angular represents an application as a tree of views.

在 Max NgWizard K 的 another article 中,我找到了工厂的定义:

Factories describe the structure of a component view and are used when instantiating the component.

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

问题:

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

What exactly are factories in Angular(2+)?

Factory是Gang of Four提到的设计模式之一(基本上他们写了一本关于他们发现的设计模式的书)。

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

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

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


想想,像这样:

假设你正在制作一个 2D 射击游戏,你必须从枪管中射出子弹。

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

它变得高度可扩展,因为您只需更改枚举,工厂就会为您制作。

您不必手动实例化它。


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

Are there scenarios that a developer benefits form knowing how they work?

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

例如大量的*ngIf,或者*ngSwitchCase可以通过简单的动态生成组件来代替

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

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

Reference for understanding the above code: Dynamically Creating Components

'A factory' 在这种情况下是 ComponentFactory, a class that has create method that implements Factory method pattern.

的一个实例

当调用 componentFactory.create 时(直接调用或通过 ComponentFactoryResolver - which is essential for dynamic components, as linked article 解释),将创建新的组件实例。

总的来说工厂是一种创造型设计模式。它是一个用于创建其他对象的对象——形式上,工厂是一个函数或方法,returns 个不同原型的对象或 class 来自某个方法调用的对象。

来自Angular docs

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

The Angular compiler extracts the metadata once and generates a factory for TypicalComponent. When it needs to create a TypicalComponent instance, Angular calls the factory, which produces a new visual element, bound to a new instance of the component class with its injected dependency.

这是幕后发生的事情。但是您也可以使用 ComponentFactoryResolver 创建动态组件 (Dynamic component loader)

//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;
}

另请阅读这篇关于 how the component factories work in Ivy 的文章。