Angular(v5.2.10)Snackbar
- |简介| -
我有一个Angular组件(我们称之为“Parent”)初始化一个名为snackBar
的Angular材质Snackbar。传入的是SnackbarMessage
,另一个组件包含一个包含快餐栏标记的模板。在这种情况下,使用snackBar.openFromComponent(SnackBarMessage)
是必要的,因为我需要在快餐栏中使用的不仅仅是纯文本[比如标记,点击事件等] snackBar.open(message, action)
是不够的。
的 - |代码| -
“父级”组件:
@Component({
selector: 'app-parent',
templateUrl: './parent.component.html'
})
export class Parent implements AfterViewInit {
public constructor(public snackBar: MatSnackBar) { }
public ngAfterViewInit(): void {
this.snackBar.openFromComponent(SnackbarMessage);
}
public dismissSnackbar(): void {
this.snackBar.dismiss();
}
}
“SnackbarMessage”组件:
@Component({
selector: 'app-snackbar-message',
templateUrl: './snackbar-message.html'
})
export class SnackbarMessage { }
“snackbar-message.html”标记:
<p>(Snackbar message)</p>
<button type="button" (click)="dismissSnackbar();">Dismiss</button>
的 - |问题| -
在导入的SnackbarMessage
模板(snackbar-message.html)中,我需要调用Parent组件的dismissSnackbar();
,我们如何使用此Angular应用程序的当前封装来做到这一点?
答案 0 :(得分:6)
您实际上不需要调用父组件的“dismissSnackbar()”方法来关闭快餐栏。您可以简单地将“MatSnackBar”注入“SnackbarMessage”组件,并在该注入的“MatSnackBar”实例上调用“dismiss()”方法。正如在docs中所写的,这将隐藏当前可见的Snackbar,即在您的示例中使用“SnackbarMessage”组件打开的Snackbar。以下是您更新的“SnackbarMessage”组件: -
“SnackbarMessage”组件:
@Component({
selector: 'app-snackbar-message',
templateUrl: './snackbar-message.html'
})
export class SnackbarMessage {
constructor(public snackBar: MatSnackBar) {}
public dismissSnackbar(): void {
this.snackBar.dismiss();
}
}
答案 1 :(得分:3)
我今天使用MatSnackBar.openFromTemplate
而不是MatSnackBar.openFromComponent
解决了一个与您类似的问题。通过这种方法,子组件的所有功能都可以直接从父组件访问。
“父组件”在MatSnackBar
和SnackBarMessageComponent
之间充当“调解人”类。现在,SnackBarMessageComponent
与MatSnackBar分离,成为一个普通的组件,可以重命名为MessageComponent
。您可以使用普通的@Input
和@Output
在父级和子级组件之间发送和接收数据。您可以根据需要添加任意数量的@Input
或@Output
。
代码说了1000多个字:
<h1>parent component</h1>
<ng-template #snackBarTemplate>
<app-message [msg]="message" (onDismissClick)="dismissSnackbar"></app-message>
</ng-template>
@Component({
selector: 'app-parent',
templateUrl: './parent.component.html'
})
export class Parent implements AfterViewInit {
@ViewChild('snackBarTemplate')
snackBarTemplate: TemplateRef<any>;
public message: string;
public constructor(public snackBar: MatSnackBar) { }
public ngAfterViewInit(): void {
this.message = '(Snackbar message)';
this.snackBar.openFromTemplate(snackBarTemplate);
}
public dismissSnackbar(): void {
this.snackBar.dismiss();
}
}
@Component({
selector: 'app-message',
templateUrl: './message.html'
})
export class MessageComponent {
@Input()
msg: string;
@Output()
onDismissClick= new EventEmitter<any>();
dismissClicked() {
this.onDismissClick.emit(null);
}
}
<p>{{msg}}</p>
<button type="button" (click)="dismissClicked()">Dismiss</button>
(以上代码尚未经过测试)
答案 2 :(得分:2)
但是,如果您希望面向未来的组件,则应使用服务。通过服务,您可以从应用程序的任何位置关闭您的零食店 - 而不仅仅是他的方法中的零食栏消息组件。
创建一个可观察的流,并在您的零食栏组件中订阅它。它只会传递一个布尔值(true或false),每次在流中发出新值时,您都可以使用该值切换快餐栏组件。
简单示例:
@Injectable()
export class SnackbarService {
status: BehaviorSubject<boolean> = new BehaviorSubject(false);
status$: Observable<boolean> = this.status.asObservable();
}
@Component({
selector: 'app-snackbar-message',
templateUrl: './snackbar-message.html'
})
export class SnackbarMessage {
open: boolean = false;
constructor(public snackbarService: SnackbarService) {
snackbarService.status$.subscribe((open: boolean) => this.open = open);
}
}
现在,从你的应用程序的任何地方,你所要做的就是打开小吃吧:
snackbarService.status.next(true);
或关闭小吃店:
snackbarService.status.next(false);
如果您希望获得更多案例而不仅仅是打开/关闭,您可以使用具有不同值的枚举:
export enum SnackbarStatus {
Open,
Closed,
SomethingElse
}
在您的可观察流中传递枚举,而不是布尔值:
@Injectable()
export class SnackbarService {
status: BehaviorSubject<SnackbarStatus> = new BehaviorSubject(SnackbarStatus.Closed);
status$: Observable<SnackbarStatus> = this.status.asObservable();
}
答案 3 :(得分:0)
使用ComponentRef调用您的方法。
MyCustomSnackBarComponent 和您的自定义方法
public miMethod(): void {
console.log('call from parent');
}
在其中创建 MyCustomSnackBarComponent 实例的组件:
const snackBarRef = this.snackbar.openFromComponent(MyCustomSnackBarComponent);
snackBarRef.instance.miMethod();
如果您的方法有参数,此解决方案仍然适用