8

I was reading an article of Max NgWizard K, about how Angular updates the DOM. I came across the following:

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.

In another article from Max NgWizard K I found the definition of a factory:

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

I'm not really sure what is meant with this.

Questions:

  1. What exactly are factories in Angular(2+)?
  2. Are there scenarios that a developer benefits form knowing how they work?
Willem van der Veen
  • 33,665
  • 16
  • 190
  • 155

3 Answers3

9

What exactly are factories in Angular(2+)?

Factory is one of the design patterns mentioned by Gang of Four (Basically they wrote a book on the design patterns they discovered).

Design Patterns help programmers solve common development tasks in a specific way.

And in this case, the Factory pattern helps in instantiation and creation of Objects.

It is also known as the Virtual Constructor.


Think of it, like this:

Say you are making a 2D shooter game, and you have to shoot bullets out of barrels.

Instead of instantiating bullets like new Bullet(), every time trigger is pulled, you can use a factory to create bullets, i.e. WeaponsFactory.createInstance(BulletTypes.AK47_BULLET).

It becomes highly scalable, since all you have to do is change the enum and the factory will make it for you.

You won't have to manually instantiate it.


That is what angular does, it automatically creates factory of all the components. Which makes its job easier.

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

You don't have to know the inner workings of a Factory to use Angular, but it's useful for creating components dynamically!

e.g. A lot of *ngIf, or *ngSwitchCase can be replaced by a simple dynamic generation of components

Components can be created dynamically like this:

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

Abhijit Kar ツ
  • 1,732
  • 1
  • 11
  • 24
  • Okay so they are referring to the design pattern, I heard of this pattern before but didn't realize they were referring to this. – Willem van der Veen Mar 05 '18 at 17:36
  • I was struggling to figure out the reason why a factory was any better than just instantiating a new object... however I presume this is primarily because a factory can load the object with services using DI in a way that you would have to do manually using `new MyObject()`. Is that correct? – Peter Nixey Apr 26 '22 at 10:39
  • Yes you got it. If objects are created via factory, you don't have to supply the raw materials, i.e. initial values. The factory will hide all those details from us, thereby making our lives easier. – Abhijit Kar ツ Apr 26 '22 at 14:12
1

'A factory' in this case is an instance of ComponentFactory, a class that has create method that implements Factory method pattern.

When componentFactory.create is called (either directly or via ComponentFactoryResolver - which is essential for dynamic components, as linked article explains), new component instance is created.

Estus Flask
  • 206,104
  • 70
  • 425
  • 565
0

In general factory is a creational design pattern. It is an object for creating other objects – formally a factory is a function or method that returns objects of a varying prototype or class from some method call.

From the 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.

This is something which happens behind the scenes. But you create dynamic components using ComponentFactoryResolver as well (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;
}

Also read this article about how the component factories work in Ivy.

Nipuna
  • 6,846
  • 9
  • 64
  • 87