angulartypescriptangular-signals

How to set signal-based input value of dialog component instance?


Today, when we use a component in a dialog, we can pass the value of an input this way:

@Component({
  selector: 'app-foo',
  template: '{{ data }}',
})
export class FooComponent {
  @Input() data: IFooData | null = null;
}
const dialogRef = this.dialog.open(FooComponent);
dialogRef.componentInstance.data = ...; // <-- we can pass the value here

(See Angular 2: Set @Input variables in Dialog Component)

How do you do the same with a signal-based input?

@Component({
  selector: 'app-foo',
  template: '{{ data }}',
})
export class FooComponent {
  data = input<IFooData | null>(null)
}

Note: I know that I could use MatDialogConfig.data + MAT_DIALOG_DATA,
but I do not want to couple my FooComponent with the dialog concept.


Solution

  • We can use setInput of the componentRef to set signal values.

    MatDialogRef - Source Code

    const dialogRef = this.dialog.open(FooComponent);
    dialogRef.componentRef.setInput('data', { test: 1});
    

    Using Signals:

    If you want it to be reactive you have to leverage effect to update the input when the signal value changes.

    export class SomeComponent {
      private injector = inject(Injector);
      testSignal = signal(1);
      private effectRef;
      private dialogRef;
      open() {
        this.dialogRef = this.dialog.open(FooComponent);
        this.effectRef = effect(() => {
          dialogRef.componentRef.setInput('data', { test: this.testSignal() });
        }, { injector: this.injector });
      }
    
      ngOnDestroy() {
        this.effectRef.destroy();
      }