Angular: Create my own *ngIf

Let’s call it as *myIf

Allen Kim
Digital-Heart

--

https://github.com/angular/angular/blob/10.0.2/packages/common/src/directives/ng_if.ts#L10-L238Photo by Adi Goldstein on Unsplash

Have you ever thought of making your own *ngIf?

It seems not easy to create something like an Angular-core built-in-like directive. First, it seems not easy to make a directive to work, which starts with with *. Second, it seems there are some complicated feature inside the weird looking directive.

Let’s look at the actual source code. This is the actual code of *ngIf at github.

To create *myIf, a simpler version of *ngIf, it seems necessary to understand ViewContainerRef and TemplateRef. The more detail about these are at the end.

HTML

<div *myIf="show">
This is controlled by *myIf="show", not *ngIf
</div>

The above Angular-style html is the same as the following.

<ng-template [myIf]="show">
<div>
This is controlled by *myIf="show", not *ngIf
<br/> Date: {{myDate}}
</div>
</ng-template>

Javascript

  • NOT to show any, execute viewContainer.clear()
  • To show all, execute viewContainer.createEmbeddedBiew(templateRef)
@Directive({selector: '[myIf]'})
export class MyIf {
@Input()
set myIf(condition) {
this.viewContainer.clear();
if (condition) {
this.viewContainer.createEmbeddedView(this.templateRef);
}
}
constructor(
private viewContainer: ViewContainerRef,
private templateRef: TemplateRef<any>
) {}
}

This is the result when it’s implemented

The below section is about understanding of ElementRef, ViewContainerRef, and TemplateRef. The following code may help you little better. The running demo is at stackblitz.

<!-- Component ViewContainerRef in constructor -->
<my-component> <!-- ElementRef in constructor -->
<!--
@Component({
selector: 'my-component',
template: `
<div #el>div</div> <-- ElementRef el
<ng-container #vc></ng-container> <-- ViewContainerRef vc
<ng-template #tpl> <-- TemplateRef tpl
<div>in ng-template</div>
</ng-template>`
})
-->
<my-component>
<!-- Directive ViewContainerRef in constructor -->
<ng-template [my-directive]> <!-- TemplateRef in constructor
<div>Within ng-template [my-directive]</div>
</ng-template>
  • ViewContainerRef : Reference for view container, it represents a container where one or more views can be attached..
  • TemplateRef: It holds a reference to its host element, which is <ng-template>
  • ElementRef: A wrapper around a native element inside of a View.

Hope this make your job.

Happy coding :)

This article is a part of Angular Random How-Tos. You may find some useful articles for your daily development.

Do you think this useful? If so please;
*
Clap 👏 button below️ to let others to see this too.
* Follow Allen on Twitter (@allenhwkim)

References:

--

--