[Fixed] How to pass a function from one component to an other using Angular?

Issue

I have the following in my driver-list.component.html file:

<button class="btn btn-outline-primary mr-2" (click)="open('focusFirst')">
  <div>Open confirm modal</div>
  <div class="text-dark" aria-hidden="true"><small>&times; button will be focused</small></div>
</button>

And here is my driver-list.component.ts

UPDATED driver-list.component.html

    @Component({
  selector: 'app-driver-list',
  templateUrl: './driver-list.component.html',
  styleUrls: ['./driver-list.component.css']
})
export class DriverListComponent implements OnInit {

  ...

@Component({
  selector: 'ngbd-modal-confirm',
  template: `
    <div class="modal-header">
      <h4 class="modal-title" id="modal-title">Profile deletion</h4>
      <button type="button" class="close" aria-describedby="modal-title" (click)="modal.dismiss('Cross click')">
        <span aria-hidden="true">&times;</span>
      </button>
    </div>
    <div class="modal-body">
      <p><strong>Are you sure you want to delete <span class="text-primary">"John Doe"</span> profile?</strong></p>
      <p>All information associated to this user profile will be permanently deleted.
        <span class="text-danger">This operation can not be undone.</span>
      </p>
    </div>
    <div class="modal-footer">
      <button type="button" class="btn btn-outline-secondary" (click)="modal.dismiss('cancel click')">Cancel</button>
      <button type="button" class="btn btn-danger" (click)="modal.close('Ok click')">Ok</button>
    </div>
  `
})
export class NgbdModalConfirm {
  constructor(public modal: NgbActiveModal) {}
}

const MODALS: {[name: string]: Type<any>} = {
  focusFirst: NgbdModalConfirm
};

@Directive({
  selector: "[openClick]",
})
export class NgbdModalFocus {
  @Input() name!: string;
  withAutofocus = `<button type="button" ngbAutofocus class="btn btn-danger"
      (click)="modal.close('Ok click')">Ok</button>`;

  constructor(private _modalService: NgbModal) {}

  @HostListener("click", ["$event"])
  open(name: string) {
    this._modalService.open(MODALS[name]);
  }
}

So right now the modal appears, but it’s completely emty. I realise I have to add to the other two component as well. They have the templates inside of them to format the modal messages. Should I use directives there as well?

Solution

This is what directives are for!

import { Directive, Input, HostListener } from "@angular/core";

@Directive({
  selector: "[openClick]",
})
export class open {
  @Input() name: string;

  constructor(
    private _modalService: NgbModal
  ) {}

  @HostListener("click", ["$event"])
  open(event) {
     this._modalService.open(MODALS[this.name]);
   }
}

Then on your button, just put

<button class="btn btn-outline-primary mr-2" openClick name="focusFirst">
  <div>Open confirm modal</div>
  <div class="text-dark" aria-hidden="true"><small>&times; button will be focused</small></div>
</button>

<button class="btn btn-outline-primary" openClick name="autoFocus">
  <div>Open confirm modal with `ngbAutofocus`</div>
  <div class="text-dark" aria-hidden="true"><small>Ok button will be focused</small></div>
</button>

Here’s the docs on directives: https://angular.io/api/core/Directive

Make the directive in a separate place and import them into the needed modules.

Leave a Reply

(*) Required, Your email will not be published