4

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?

Indivon
  • 1,784
  • 2
  • 17
  • 32
  • how about passing a templateRef from the component which calls the function in the service (so instead of `openForm()`, do `openForm(template: TemplateRef)`? – Moshezauros Jan 13 '21 at 17:33
  • That‘s exactly what I want to prevent. Otherwise every component that uses the service (or even through other services) must have a template. And in a CRUD service this would always the same template for the save and cancel buttons – Indivon Jan 13 '21 at 18:45

1 Answers1

6

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.

Casper Bang
  • 793
  • 2
  • 6
  • 24
Moshezauros
  • 2,493
  • 1
  • 11
  • 15
  • That could be a solution. Am I right that there could only be one template at once? – Indivon Jan 14 '21 at 16:35
  • with the listed solution, but you can extend it and create an object with many templates (or array, or Record), I was just trying to convey the general idea, but then you also have to specify the template when opening – Moshezauros Jan 14 '21 at 17:39