Angular(v5.2.10)中Snackbar的openFromComponent组件通信问题咨询
这个问题很典型——因为SnackbarMessage是被MatSnackBar动态渲染的,它和Parent组件并不是传统的父子组件关系(没有在Parent模板里直接嵌套),所以模板里直接调用dismissSnackbar()肯定会找不到方法。这里有两个实用的解决方案,看你的需求来选:
方案一:利用MatSnackBarRef直接关闭(推荐,解耦)
Angular Material在你用openFromComponent创建Snackbar组件时,会自动把MatSnackBarRef注入到该组件中,我们可以直接用它来关闭Snackbar,完全不需要依赖父组件的方法,更符合组件职责分离。
首先修改SnackbarMessage组件:
import { Component } from '@angular/core'; import { MatSnackBarRef } from '@angular/material/snack-bar'; @Component({ selector: 'app-snackbar-message', templateUrl: './snackbar-message.html' }) export class SnackbarMessage { // 注入SnackBar的引用 constructor(public snackBarRef: MatSnackBarRef<SnackbarMessage>) {} }
然后更新你的模板,直接调用snackBarRef的dismiss方法:
<p>(Snackbar message)</p> <button type="button" (click)="snackBarRef.dismiss()">Dismiss</button>
这样点击按钮就能直接关闭Snackbar,而且Parent组件里的dismissSnackbar()方法依然可以正常使用,比如你需要在其他地方手动关闭的场景。
方案二:传递回调给Snackbar组件(适合父组件有额外关闭逻辑的情况)
如果你的dismissSnackbar()方法里除了关闭Snackbar,还有其他业务逻辑要执行,那可以通过MAT_SNACK_BAR_DATA把这个方法作为回调传递给SnackbarMessage组件。
首先修改Parent组件的ngAfterViewInit方法,传入包含回调的数据:
public ngAfterViewInit(): void { this.snackBar.openFromComponent(SnackbarMessage, { data: { // 把父组件的方法作为回调传进去 onDismiss: () => this.dismissSnackbar() } }); }
然后在SnackbarMessage组件里注入MAT_SNACK_BAR_DATA:
import { Component, Inject } from '@angular/core'; import { MAT_SNACK_BAR_DATA } from '@angular/material/snack-bar'; @Component({ selector: 'app-snackbar-message', templateUrl: './snackbar-message.html' }) export class SnackbarMessage { constructor(@Inject(MAT_SNACK_BAR_DATA) public data: { onDismiss: () => void }) {} }
最后更新模板调用这个回调:
<p>(Snackbar message)</p> <button type="button" (click)="data.onDismiss()">Dismiss</button>
这样点击按钮时,就会触发父组件的dismissSnackbar()方法,执行其中的所有逻辑。
内容的提问来源于stack exchange,提问作者Cody Tolene
相关产品推荐
相关产品推荐

