Angular 8 override template from customer specific module

Viewed 803

I am building a system where the core should be able to handle different customers and I would like to be able to lazy load in a "customer specific" module that overrides templates for my different components, let's say I have a ShowBlogComponent and it has

<ng-container *ngTemplateOutlet="showblog"></ng-container>

<ng-template #showblog>
    <div>SHOW MY BLOG FROM CORE</div>
</ng-template>

And then i would like to have a module MyCustomerModule where we load a new html file with:

<ng-template #showblog>
    <div>SHOW MY BLOG FROM MyCustomer</div>
</ng-template>

That overrides the HTML template for that specific customer.

How can I make this happen?

How i would do it in angularJs:

templateUrl: getBlogTemplate()


function getBlogTemplate() {
   if(customer) 
      return "customerBlogTemplate.html";
   else 
      return "baseBlogTemplate.html";
}
3 Answers

You can create base class for ShowBlogComponent - showBlogComponentBase.ts for example. If you use routing to different modules with lazy - each module route can lead you to specific descendant of showBlogComponentBase.

In each component file you can extend base class and use different local templateUrl html, but having same logic behind it.

So you can have:

common.module.ts with exported (or lazy-routed) common-show-blog.component.ts extends showBlogComponentBase.ts

and

< your-custom-module >.module.ts with exported (or lazy-routed) < your-custom-module >-show-blog.component.ts extends showBlogComponentBase.ts

I believe you are having control on which module will be getting displayed in your current router outlet.

Show blog component will change to :-

Assuming selector as :- 'show-blog'

<ng-template #showblog>
   <ng-content><ng-content>
</ng-template>

Blog from core will change to :-

<show-blog>
   <div>SHOW MY BLOG FROM CORE</div>
<show-blog>

Blog from customer will change to :-

<show-blog>
   <div>SHOW MY BLOG FROM MyCustomer</div>
<show-blog>

Actually maintaining different templates for different customers inside a single component will be hard to maintain at the later point of the time. Not only that you also bundling the code to the different use cases which were written for other customers.

We have a concept called content Projection in angular which is actually a lazy-loaded technique. By using content projection consumers of the client can control the component what was the template which was supposed to use.

An in-depth article about the content projection and how it works

Angular university: https://blog.angular-university.io/angular-ng-content/

Coming to your question, you're supposed to use <ng-content></ng-content> syntax is the placeholder where you want to change the template for one client to another client.

Consume of the component should pass you the template which was supposed to be used

Example :

 @Component({
  selector: 'input-component',
  template: `
    <ng-content></ng-content>
  `,
  styleUrls: []
})
export class InputComponent {

}

 **Customer Consumer:** 

<input-component icon="envelope" _nghost-c0="">

   <div>SHOW MY BLOG FROM MyCustomer</div>

</input-component>

**Core Consumer** 

<input-component icon="envelope" _nghost-c0="">

   <div>SHOW MY BLOG FROM Core </div>

</input-component>
Related