All About Template In Angular By Sagar Jaybhay

Template In Details In Angular By Sagar Jaybhay

In angular component we have 2 ways to add a template, here template means the Html code which required for component.

In AngularJS, the view is a projection of the model through the HTML template. This means that whenever the model changes, AngularJS refreshes the appropriate binding points, which updates the view.

If you see below code we use inline template property in the component class.

import { Component, Input, OnInit, Output,EventEmitter } from "@angular/core";

@Component({
    selector:'rating',
    template:`
    <span>I m in rating Component</span>
    <div class="container">
    <button (click)="onClickStar()">
    <span>
    <i class="{{isClicked==true?'fa fa-star':'fa fa-star-o'}}"></i>
  </span>
  </button>
    </div>
    `    
})

export class Rating implements OnInit
{
    ngOnInit(): void {
        console.log('i m in OnInit => '+this.isClicked);
    }
    cssClass="fa fa-star-o";
   @Input('is-Favourite') isClicked:boolean;
   @Output('change') click=new EventEmitter();
   
   onClickStar()
    {
       this.isClicked=!this.isClicked;
       var newObject=       
       {
           needtopass:"demo string",
           numb:12,
           boolval:false
       }
       this.click.emit((newObject));
    }
}
All About Template In Angular By Sagar Jaybhay

Another way is that use of templateUrl property.

All About Template In Angular By Sagar Jaybhay
import { Component, Input, OnInit, Output,EventEmitter } from "@angular/core";

@Component({
    selector:'rating',
    templateUrl:'./rating.component.html'   
})

export class Rating implements OnInit
{
    ngOnInit(): void {
        console.log('i m in OnInit => '+this.isClicked);
    }
    cssClass="fa fa-star-o";
   @Input('is-Favourite') isClicked:boolean;
   @Output('change') click=new EventEmitter();
   
   onClickStar()
    {
       this.isClicked=!this.isClicked;
       var newObject=       
       {
           needtopass:"demo string",
           numb:12,
           boolval:false
       }
       this.click.emit((newObject));
    }
}

Below is external Html file present in app folder.

<h1>I am In rating</h1>
<span>I m in rating Component</span>
<div class="container">
<button (click)="onClickStar()">
<span>
<i class="{{isClicked==true?'fa fa-star':'fa fa-star-o'}}"></i>
</span>
</button>
</div>

Now the question comes in your mind which one is better template or templateUrl?

  1. First if you have small component and which required hardly 3 to 4 lines of small Html you can use template property which is inline code in that file itself.
  2. When you need a big Html code then go to external Html file which is referred by templateUrl property.
  3. If you use external Html you will get intellisense for Html but if you use inline template property intellisense is not present.
  4. If you use templateUrl property it will not make another call to render Html when webpack is applied it bundled everything and Html is present in main.js file in module.export. below is the image
All About Template In Angular By Sagar Jaybhay

How to apply the style to Component?

In angular component decorator we have 2 ways to apply styles.

  1. styleUrls
  2. styles

In these both are the arrays but you can use only one. Also if you use both the who ever is last that CSS is applied on your component Html.

So the styles which we apply here are scoped to that component only these are not applied outside of that component.

import { Component, Input, OnInit, Output,EventEmitter } from "@angular/core";

@Component({
    selector:'rating',
    templateUrl:'./rating.component.html',
    styleUrls:['./rating.component.css'],
    styles:[`
    .fa-star
    {
        color: green;
    }
    `]
})

export class Rating implements OnInit
{
    ngOnInit(): void {
        console.log('i m in OnInit => '+this.isClicked);
    }
    cssClass="fa fa-star-o";
   @Input('is-Favourite') isClicked:boolean;
   @Output('change') click=new EventEmitter();
   
   onClickStar()
    {
       this.isClicked=!this.isClicked;
       var newObject=       
       {
           needtopass:"demo string",
           numb:12,
           boolval:false
       }
       this.click.emit((newObject));
    }
}
All About Template In Angular By Sagar Jaybhay

Now the question is how angular decide to apply CSS only that Html element or scoped to that element only?

First need to understand Shadow Dom.

Shadow DOM allows hidden DOM trees to be attached to elements in the regular DOM tree — this shadow DOM tree starts with a shadow root, underneath which can be attached to any elements you want, in the same way as the normal DOM.

For more information visit link:- https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM

All About Template In Angular By Sagar Jaybhay

ViewEncapsulation in Angular:

Defines template and style encapsulation options available for Component’s Component.

enum ViewEncapsulation {
  Emulated: 0
  Native: 1
  None: 2
  ShadowDom: 3
}

It is used to encapsulate the view and in simple term shadow dom methods are applied by using simple hack by angular team. In this shadow dom is not supported by many old browsers and supported by some of safari which one is latest and chrome version 50 onwards so to compatible all angular use viewEncapsulation property. And in this Emulated is default one.

MemberDescription
Emulated: 0Emulate Native scoping of styles by adding an attribute containing surrogate id to the Host Element and pre-processing the style rules provided via styles or styleUrls, and adding the new Host Element attribute to all selectors.This is the default option.
Native: 1
None: 2Don’t provide any template or style encapsulation.
ShadowDom: 3Use Shadow DOM to encapsulate styles.For the DOM this means using modern Shadow DOM and creating a ShadowRoot for Component’s Host Element.
All About Template In Angular By Sagar Jaybhay

In this below image you can see angular by default generate some Id’s to identify the element and apply the CSS on that element only.

All About Template In Angular By Sagar Jaybhay

Ng-Content:

Now suppose I want to create one panel which is reusable and wants to plug different content on-demand so how I went do that in simple way. For that angular provide ng-content which is used for dynamic content placement.

In below code is our panel component class in which we push dynamic content.

If we add the tag <ng-content></ng-content> anywhere in our template HTML for our component. The inner content of the tags that define our component is then projected into this space.

Content projection is an Angular concept that helps developers build reusable components. It allows you to pass data from a parent component to a template of a child component.

import { Component } from '@angular/core';


@Component({
    selector:'custom-panel',
    templateUrl:'./panelDemo.component.html',
    styleUrls:['./panelDemo.component.css']
})
export class panelDemo
{

}

Below is the code for html of that panel

div class="panel panel-default">
    <div class="panel-heading">
        <ng-content select=".heading"></ng-content>
    </div>        

    <div class="panel-body">
    <ng-content select=".body"></ng-content>
    </div>
</div>

In above you can see that we add <ng-content></ng-content> in 2 places in panel heading and in panel body.

But here is the catch that in single Html I m using 2 <ng-content> so I need to identify them anyhow so I use select attribute where I give .class name by using this we can identify them.

Now below is the code for app.component.html where we push dynamic content.

<custom-panel>
    <div class="heading">
        My heading is here
    </div>
    <div class="body">
my body is here
    </div>
</custom-panel>

Now we use to identify by class name so we use

<div class="heading">

To select <ng-content> and push the content only in that div.

If your Html page contains only <ng-content> element then no need to selector of that <ng-content>

Now the output looks like this.

All About Template In Angular By Sagar Jaybhay

Ng-Container:-

In angular you cant use more than one template binding on single element.

<!-- Can't do this -->
<div *ngIf="todos" *ngFor="let todo of todos">
  {{ todo.content }}
</div>
To achive the same functionality we need to do following modification.
<div *ngIf="todos">
  <div *ngFor="let todo of todos">
    {{ todo.content }}
  </div>
</div>

Angular This solution perfectly fine but it adds extra div element in dom. So at this place ng-container comes in a picture.

<ng-container *ngIf="todos">
  <div *ngFor="let todo of todos">
    {{ todo.content }}
  </div>
</ng-container>

Angular the following code behaves same but without adding extra div to our dom element.

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *