{"id":1647,"date":"2022-01-30T22:03:40","date_gmt":"2022-01-30T21:03:40","guid":{"rendered":"https:\/\/nguenkam.com\/blog\/?p=1647"},"modified":"2022-01-30T22:03:40","modified_gmt":"2022-01-30T21:03:40","slug":"ng-template-vs-ng-container-vs-ng-content","status":"publish","type":"post","link":"https:\/\/nguenkam.com\/blog\/index.php\/2022\/01\/30\/ng-template-vs-ng-container-vs-ng-content\/","title":{"rendered":"&#8220;ng-template&#8221; VS &#8220;ng-container&#8221; VS &#8220;ng-&#8220;content"},"content":{"rendered":"\n<h4>1 &#8211; <span class=\"has-inline-color has-vivid-cyan-blue-color\">&lt;ng-template>&lt;\/ng-template><\/span><\/h4>\n\n\n\n<p>As the name suggests the &lt;<strong>ng<\/strong>&#8211;<strong>template<\/strong>> is a\u00a0<strong>template<\/strong>\u00a0element that\u00a0<strong>Angular<\/strong>\u00a0uses with structural directives ( *ngIf , *ngFor , [ngSwitch] and custom directives). These\u00a0<strong>template<\/strong>\u00a0elements only work in the presence of structural directives, which help us to define a template that doesn\u2019t render anything by itself, but conditionally renders them to the DOM.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code> &lt;div *ngIf=\u201dcondition==false ; else showNgTemplateContent\u201d> \r\n      Shouldn't be displayed \r\n  &lt;\/div>\r\n\r\r\n&lt;ng-template #showNgTemplateContent> Should be displayed\r\n&lt;\/ng-template><\/code><\/pre>\n\n\n\n<p><em>In the above example, If the condition is false then we will show the text as \u201cShouldn&#8217;t be displayed\u201d else will show ng-template content as \u201cShould be displayed\u201d<\/em><\/p>\n\n\n\n<h4>2- <span class=\"has-inline-color has-vivid-cyan-blue-color\">&lt;ng-container>&lt;\/ng-container><\/span><\/h4>\n\n\n\n<p id=\"637a\"><em>ng-container<\/em>\u00a0is an extremely simple directive that allows you to group elements in a template that doesn\u2019t interfere with styles or layout because Angular doesn\u2019t put it in the DOM.<\/p>\n\n\n\n<p id=\"acbc\">This is helpful if you don\u2019t want any extra div on DOM, you can simply use<br>ng-container. For eg: If there are two structural directives are being called on one div as below:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;div *ngIf=\"details\" *ngFor=\"let info of details\">\r\n  {{ info.content }}\r\n&lt;\/div><\/code><\/pre>\n\n\n\n<p>Attempting to compile this code will result in the following error:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Can't have multiple template bindings on one element. Use only one attribute prefixed with *<\/code><\/pre>\n\n\n\n<p>One workaround would be to separate the bindings as below:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;div *ngIf=\"details\">\r\n  &lt;div *ngFor=\"let info of details\">\r\n    {{ info.content }}\r\n  &lt;\/div>\r\n&lt;\/div><\/code><\/pre>\n\n\n\n<p>Or we can use <strong>&lt;ng-container> <\/strong><em>without adding any extra element<\/em> to the DOM at runtime:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;ng-container *ngIf=\"details\">\r\n  &lt;div *ngFor=\"let info of details\">\r\n    {{ info.content }}\r\n  &lt;\/div>\r\n&lt;\/ng-container><\/code><\/pre>\n\n\n\n<h4>3- \u00a0<span class=\"has-inline-color has-vivid-cyan-blue-color\">&lt;ng-content>&lt;\/ng-content><\/span><\/h4>\n\n\n\n<p><em>ng-content<\/em>\u00a0is used to project content into Angular components. You use the\u00a0<strong>&lt;ng-content>&lt;\/ng-content><\/strong>\u00a0tag as a placeholder for that dynamic content, then when the template is parsed Angular will replace that placeholder tag with your content. This is well known as\u00a0<strong><strong>Content Projection<\/strong><\/strong>.<\/p>\n\n\n\n<p>in others words,They are used to create configurable components. This means the components can be configured depending on the needs of its user. <\/p>\n\n\n\n<p><strong><span class=\"has-inline-color has-vivid-red-color\"><em>PS:<\/em><\/span> <\/strong><em> Components that are used in published libraries make use of\u00a0<code>&lt;ng-content><\/code>\u00a0to make themselves configurable.<\/em><\/p>\n\n\n\n<p>Consider a simple\u00a0<code>&lt;project-content><\/code>\u00a0component:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" src=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2022\/01\/image-34.png\" alt=\"\" class=\"wp-image-1648\" width=\"508\" height=\"363\" srcset=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2022\/01\/image-34.png 732w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2022\/01\/image-34-300x214.png 300w\" sizes=\"(max-width: 508px) 100vw, 508px\" \/><\/figure>\n\n\n\n<p>In parent.component.html, <strong>&lt;project-content><\/strong> selector is used to show data of <strong><em>Project-content<\/em><\/strong> component<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" src=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2022\/01\/image-35.png\" alt=\"\" class=\"wp-image-1649\" width=\"437\" height=\"99\" srcset=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2022\/01\/image-35.png 720w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2022\/01\/image-35-300x68.png 300w\" sizes=\"(max-width: 437px) 100vw, 437px\" \/><\/figure>\n\n\n\n<p>The HTML content passed within the opening and closing tags of\u00a0<code>&lt;project-content><\/code>\u00a0component is the content to be projected. This is what we call\u00a0<strong><strong>Content Projection<\/strong><\/strong>. The content will be rendered inside the\u00a0<code>&lt;ng-content><\/code>\u00a0within the component.\u00a0<\/p>\n\n\n\n<p>This allows the  parent component of\u00a0<code>&lt;project-content><\/code>\u00a0component to pass any custom footer within the component and control\u00a0<em>exactly<\/em>\u00a0how they want it to be rendered.<\/p>\n\n\n\n<p><span class=\"has-inline-color has-vivid-red-color\"><strong><em>PS:<\/em><\/strong><\/span> <em>In the example above, we set a single content projection, but we can also make multiple projections.<\/em><\/p>\n\n\n\n<h4><span class=\"has-inline-color has-vivid-red-color\">Multiple Projections:<\/span><\/h4>\n\n\n\n<p>Instead of every content projected inside a single\u00a0<code>&lt;ng-content><\/code>, you can also control how the contents will get projected with the\u00a0<code>select<\/code>\u00a0attribute of\u00a0<code>&lt;ng-content><\/code>. It takes an element selector to decide which content to project inside a particular\u00a0<code>&lt;ng-content><\/code><\/p>\n\n\n\n<p>Here\u2019s how:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" src=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2022\/01\/image-36.png\" alt=\"\" class=\"wp-image-1650\" width=\"495\" height=\"285\" srcset=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2022\/01\/image-36.png 696w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2022\/01\/image-36-300x173.png 300w\" sizes=\"(max-width: 495px) 100vw, 495px\" \/><\/figure>\n\n\n\n<p>We have modified the\u00a0<code>&lt;project-content><\/code>\u00a0definition to perform Multi-content projection. The\u00a0<code>select<\/code>\u00a0attribute selects the type of content that will be rendered inside a particular\u00a0<code>&lt;ng-content><\/code>. Here we have first\u00a0<code>select<\/code>\u00a0to render header\u00a0<code>h1<\/code>\u00a0element. If the projected content has no\u00a0<code>h1<\/code>\u00a0element it won\u2019t render anything. Similarly the second\u00a0<code>select<\/code>\u00a0looks for a\u00a0<code>div<\/code>. The rest of the content gets rendered inside the last\u00a0<code>&lt;ng-content><\/code>\u00a0with no\u00a0<code>select<\/code>.<\/p>\n\n\n\n<p>Calling the component from the parent component will look like:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" src=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2022\/01\/image-37.png\" alt=\"\" class=\"wp-image-1651\" width=\"511\" height=\"175\" srcset=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2022\/01\/image-37.png 751w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2022\/01\/image-37-300x103.png 300w\" sizes=\"(max-width: 511px) 100vw, 511px\" \/><\/figure>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>1 &#8211; &lt;ng-template>&lt;\/ng-template> As the name suggests the &lt;ng&#8211;template> is a\u00a0template\u00a0element that\u00a0Angular\u00a0uses with structural directives ( *ngIf , *ngFor , [ngSwitch] and custom directives). These\u00a0template\u00a0elements only work in the presence of structural directives, which help us to define a template that doesn\u2019t render anything by itself, but conditionally renders them to the DOM. In the [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1652,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[37],"tags":[481,480,470,469],"_links":{"self":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/1647"}],"collection":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=1647"}],"version-history":[{"count":1,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/1647\/revisions"}],"predecessor-version":[{"id":1653,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/1647\/revisions\/1653"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/media\/1652"}],"wp:attachment":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=1647"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=1647"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=1647"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}