A structural directive changes the HTML document by adding or removing content from a template. Use one when content should appear conditionally or repeat for values in a data source. Unlike a visibility binding, a conditional structural directive destroys and re-creates content rather than leaving it in the document and hiding it. section 15.0 section 15.2.2
The familiar *ngIf and *ngFor forms use an asterisk as shorthand. Angular expands that concise form into an ng-template containing the element and its content. The full form applies the directive to ng-template directly; both forms provide the content that the directive controls. In the concise form, do not omit the asterisk. section 12.2.1 section 15.2
Show a table only when selected
Bind a checkbox to showTable, then place the table inside <ng-template [paIf]="showTable">. When the checkbox is checked, the directive adds the table; when unchecked, it removes it. Bindings and directives inside the table remain part of the template used to create that content. section 15.2 section 15.2.2
To build an iterating structural directive:
- Define a class with @Directive, and receive a ViewContainerRef and TemplateRef in its constructor. The container controls the views created from the template. section 15.0 section 15.3
- Bind a data source through an input such as paForOf. With the full ng-template syntax, let-item names the implicit value available to bindings inside each generated view. The data-source attribute must end in Of to support the concise syntax. section 15.3
- Create an embedded view for each source value, supplying that value through a context object's $implicit property. Declare the directive in its Angular module before using it in a component template. section 15.3 section 15.2.2
Listing 15.9. The contents of the iterator.directive.ts file in the src/app folder
import { Directive, ViewContainerRef, TemplateRef, Input}
from "@angular/core";
@Directive({
selector: "[paForOf]"
})
export class PaIteratorDirective {
constructor(private container: ViewContainerRef,
private template: TemplateRef<Object>) { }
@Input("paForOf")
dataSource: any;
ngOnInit() {
this.container.clear();
for (let i = 0; i < this.dataSource.length; i++) {
this.container.createEmbeddedView(this.template,
new PaIteratorContext(this.dataSource[i]));
}
}
}
class PaIteratorContext {
constructor(public $implicit: any) { }
}
The iterator implementation shows how the input, view container, template, and $implicit context work together to generate one table row per product. section 15.3
Choose the update strategy with care. A page-button directive can clear its container and rebuild every view when the page count changes, but repeated rebuilding can be expensive. Changes to properties of an object already supplied as a view's context are reflected in dependent bindings automatically; changes to a collection require separate detection and handling. section 5.5.4 section 15.3.3 section 15.0

