How to inject snackBarRef into a component with openFromComponent

App*_*mer 5 reference snackbar angular6

The latest Material documentation says the following..

If you want to close a custom snack-bar that was opened via openFromComponent, from within the component itself, you can inject the MatSnackBarRef.

but they don't show you how to do it.

In their example, they nest a component within the same .ts file as the calling module, and they don't show the ref being passed in. But since I want to use a more centralized approach, I have created a new module using...

ng g component components/snackbar
Run Code Online (Sandbox Code Playgroud)

This way, I should be able to pass in @Input to render different html depending on need. This would further allow for things like branding, multiple buttons, and for html buttons to dismiss the snackbar… as long as they have access to a ref!

My calling .ts has the following...

var snackBarRef : any;
snackBarRef = this.snackBar.openFromComponent(SnackbarComponent, {data : snackBarRef});
Run Code Online (Sandbox Code Playgroud)

the component .ts has the following constructor...

constructor(public snackBar: MatSnackBar, @Inject(MAT_SNACK_BAR_DATA) public data: any) { }
Run Code Online (Sandbox Code Playgroud)

My expectations are that I could then create a function in the component that could act upon snackBarRef.dismiss(); as needed. However, when I run the app, I get the following error...

Uncaught (in promise): Error: StaticInjectorError(AppModule)[SnackbarComponent -> InjectionToken MatSnackBarData]: 
  StaticInjectorError(Platform: core)[SnackbarComponent -> InjectionToken MatSnackBarData]
Run Code Online (Sandbox Code Playgroud)

Just to make sure I had the plumbing right, I swapped out {data : snackBarRef} to {data : 0}. By doing that, I don't see any errors and I can use the data value of 0 for other things, but of course I also don't have a handle on the ref to use locally.

Is there another way to pass the snackBarRef into the component other than using the data section of the openFromComponent? or, alternatively, is there a way to pass the ref through the data section without causing the error?

小智 11

我今天遇到了同样的问题,但是找到了解决方案:

import { Component, Inject } from '@angular/core';
import { MAT_SNACK_BAR_DATA, MatSnackBarRef } from '@angular/material';

@Component({
  selector: 'my-notification',
  template: `
    <p>{{ data.message }}</p>
    <button mat-raised-button
            color="accent"
            (click)="snackBarRef.dismiss()">{{ data.action }}</button>
  `,
})
export class TestNotificationComponent {
  constructor(
    public snackBarRef: MatSnackBarRef<TestNotificationComponent>,
    @Inject(MAT_SNACK_BAR_DATA) public data: any,
  ) {}
}
Run Code Online (Sandbox Code Playgroud)

Angular将处理注入SnackBarRef。

  • 不能说“是”!感谢您的修复。顺便说一句......在调用@Component 进行实例化时,我不再需要使用本地 SnackRef。换句话说,我改变了 this.SnackRef = this.snackBar.openFromComponent(SnackbarComponent, {data : id}); 到 this.snackBar.openFromComponent(SnackbarComponent, {data : id});。这样我就不会得到一个没有做任何其他事情的孤儿参考。很好的答案!谢谢。 (2认同)

小智 5

Improving on Dario's answer, If one wants to capture the action button click in the calling component, one should use snackBarRef.dismissWithAction() in (click) event.

<button mat-raised-button color="accent" (click)="snackBarRef.dismissWithAction()">{{ data.action }}</button>
Run Code Online (Sandbox Code Playgroud)