Dieser Beitrag ist Teil 5 von 5 in the series WPS @ Angular

This is Part 5 of Best Practices for Not Getting Lost When Building Real-World Applications

by Richard Voß @richard_voss

Since last year we find ourselves developing web applications for our customers using Angular 4+. Angular is a popular framework (some call it a platform) for developing web-based front-end applications using Typescript, HTML and CSS. It is open-source and primarily driven by Google.

The framework makes it easier and more fun to structure complex user interfaces, promotes re-use of components and — most valuable — allows test-driven development in the front-end.

Despite all of the greatness of Angular, even with the framework there are lots of mistakes left to make. We have identified a few good patterns and pitfalls that we collected.

This article is part of a series that offers a glimpse into our “Angular Pattern Library”. Last time we were talking about avoiding inheritance for components. Today we’ll look at one of the most important techniques for correctly modularizing component templest.

👍 Use Advanced Template Transclusion

You cannot avoid template transclusion if you want to avoid template duplication.

The Angular Tutorial is not very detailed on transclusion, <ng-content> goes almost unnoticed when working through it. You have to consult other sources to find out about the possibilities.

So now that we’re still trying to factor out components wherever we can, we find that sometimes not just blocks of template, but template structures repeat, like “header + content + footer”, or “left + right” (comparisons) or “label + control + messages” (forms). The glue in between is what I call abstract structure and it tends to be always the same in an application and you don’t want to repeat it.

To do that you can use <ng-content select="...">, but we have found using <ng-template> and <ng-container> is the more powerful alternative, because they are not just re-arranging DOM nodes, but actually make templates become named input parameters for components.

@Component({
  selector: 'abstract-structure',
  template: `
    <header>
      <ng-container [ngTemplateOutlet]="top"></ng-container>
    </header>
    <aside>
      <ng-container [ngTemplateOutlet]="left"></ng-container>
    </aside>
    <div class="content">
      <ng-container [ngTemplateOutlet]="bottom"></ng-container>
    </div>`
})
export class AbstractStructureComponent {
  @ContentChild('top') top: TemplateRef<any>;
  @ContentChild('left') left: TemplateRef<any>;
  @ContentChild('bottom') bottom: TemplateRef<any>;
}

@Component({
  selector: 'concrete-structure',
  template: `
    <abstract-structure>
      <ng-template #left><a></a></ng-template>
      <ng-template #top><b></b></ng-template>
      <ng-template #bottom><c></c></ng-template>
    </abstract-structure>`
})
export class ConcreteStructureComponent {

}

The advantages are:

  1. You can reduce the amount of boilerplate HTML elements in the resulting DOM, which is good news when it comes to CSS styling.
  2. Instantiation of the components in a template can be controlled and deferred, which can improve performance. For example, one of the templates may not be displayed at all depending on a condition. Not instantiating it will save DOM nodes and change detection time.
  3. Although it involves more code, the intention here becomes very clear. You can read @ContentChild('x') almost like @Input('x'), so the interface of the AbstractStructureComponent is really obvious without having to look at it’s template.

Where to go from here…

I recommended to read about this in depth and even more to get started. Once you are comfortable with using templates at runtime, many doors to powerful re-use of components open.

This time, i cannot tell the headline of the next article. Feel free to give me feedback or ask me anything.

Seriennavigation<< Angular @ WPS Part 4: Avoid Component Class Inheritance