Search code examples
angulartypescriptng-zorro-antd

Create TemplateRef in a Angular 10 service


We use ngZorro in an Angular 10 project. Now I want to open the drawer (https://ng.ant.design/components/drawer/en) to show forms. The scenario is a list of e.g. products and on a click on one of the product, it's form should be opened in the drawer.

I'm using the NzDrawerService to create the drawer, but I cannot set any footer (called nzFooter).

For example, there is a ProductFormComponent, so in my ProductService.ts I can just call:

openForm(){
  const drawerRef = this.drawerService.create({
      nzTitle: 'My Title',
      nzContent: ProductFormComponent
  });
  drawerRef.open()
}

Now, there is also an option for a predefined footer (nzFooter?: string | TemplateRef<{}>), where I want to add the buttons for save and cancel. Now the question: How can I get a TemplateRef here, because the function is called in a service and not in a component?


Solution

  • If I had a single template I would want to inject to a service, I would use a "dummy" component, which I would use to inject a template into my service.

    You can add a function on the drawer service to set a templateRef:

    private template: TemplateRef<any>;
    setTemplate(template: TemplateRef<any>) {
      this.template = template;
    }
    

    the component would look like:

    @Component({
      selector: "template-injector",
      template: `
        <ng-template #myTemplate>
          <h1>Best Template!</h1>
        </ng-template>
      `,
      styleUrls: []
    })
    export class TemplateInjectorComponent implements AfterViewInit {
      constructor(private derviceService: DrawerService) {}
    
      @ViewChild("myTemplate") template: TemplateRef<any>;
    
      ngAfterViewInit(): void {
        this.derviceService.setTemplate(this.template);
      }
    }
    

    and finally, find the main component in your app and load the TemplateInjectorComponent, since the template is just <ng-template>, nothing is rendered (a good place to add it would be at the end of your layout component).

    Alternatively, instead of creating a new component, you can add it to the main app component.