我实施了一个“小吃栏服务”,显示snackbar:
snackbar.service.ts
import { Subscription } from 'rxjs/Subscription';
import { Subject } from 'rxjs/Subject';
import { Inject, Injectable, OnDestroy } from '@angular/core';
import { MatSnackBar, MdSnackBarConfig } from '@angular/material/snack-bar';
import { MdSnackBarRef, SimpleSnackBar } from '@angular/material/snack-bar';
export class SnackBarMessage {
message: string;
action: string = null;
config: MdSnackBarConfig = null;
}
@Injectable()
export class SnackBarService implements OnDestroy
{
private messageQueue: Subject<SnackBarMessage> = new Subject<SnackBarMessage>();
private subscription: Subscription;
private snackBarRef: MdSnackBarRef<SimpleSnackBar>;
constructor(public snackBar: MatSnackBar){
this.subscription = this.messageQueue.subscribe(message => {
this.snackBarRef = this.snackBar.open(message.message, message.action, message.config);
});
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
/**
* Add a message
* @param message The message to show in the snackbar.
* @param action The label for the snackbar action.
* @param config Additional configuration options for the snackbar.
*/
add(message: string, action?: string, config?: MdSnackBarConfig): void{
if ( !config ){
config = new MdSnackBarConfig();
config.duration = 10000;
}
let sbMessage = new SnackBarMessage();
sbMessage.message = message;
sbMessage.action = action;
sbMessage.config = config;
this.messageQueue.next(sbMessage);
}
}
我想按顺序显示多个零食吧:
test.component.ts
import { Component } from '@angular/core';
import { SnackBarService } from 'app/core/services/snackbar.service';
@Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.scss']
})
export class TestComponent {
constructor(public snackBarService: SnackBarService) {
this.snackBarService.add('A');
this.snackBarService.add('B');
this.snackBarService.add('C');
}
}
但是所有消息都同时显示(重叠)。
如何等待snackBar afterDismissed向messageQueue显示新消息?
答案 0 :(得分:5)
正如@Aamir Khan指出的那样 - 使用afterDismissed
,我稍微调整了你的代码。
showNext() {
if (this.msgQueue === 0) {
return;
}
let message = this.msgQueue.shift();
this.isInstanceVisible = true;
this.snackBarRef = this.snackBar.open(message.message, message.action, {duration: 2000});
this.snackBarRef.afterDismissed().subscribe(() => {
this.isInstanceVisible = false;
this.showNext();
});
}
在add()
里面添加了这个 -
this.msgQueue.push(sbMessage);
if (!this.isInstanceVisible) {
this.showNext();
}
警告 - 由于使用了标志,上面的代码可能会有一些内存泄漏和竞争条件的
答案 1 :(得分:2)
你需要使用超时方法。 在特定时间隐藏零食栏并使用超时功能打开另一个零食吧
constructor(public snackBarService: SnackBarService) {
this.snackBarService.add('A')
setTimeout(this.snackBarService.add('B'),10000);
setTimeout(this.snackBarService.add('C'),20000);
}
答案 2 :(得分:2)
这是这里的@ Ankit's Plunker。
import {Subscription} from 'rxjs';
import {Injectable, OnDestroy} from '@angular/core';
import {MatSnackBar, MatSnackBarConfig} from '@angular/material/snack-bar';
import {MatSnackBarRef, SimpleSnackBar} from '@angular/material/snack-bar';
import {SnackBarMessage} from './snackBarMessage.model';
@Injectable()
export class NotificationService implements OnDestroy {
private messageQueue: Array<any> = Array<any>();
private subscription: Subscription;
private snackBarRef: MatSnackBarRef<SimpleSnackBar>;
private isInstanceVisible = false;
constructor(public snackBar: MatSnackBar) {}
ngOnDestroy() {
this.subscription.unsubscribe();
}
/**
* Add a message
* @param message The message to show in the snackbar.
* @param action The label for the snackbar action.
* @param config Additional configuration options for the snackbar.
* @param classOverride Adds a css class on the snackbar so you can add color.
*/
show(
message: string,
action?: string,
config?: MatSnackBarConfig,
classOverride: string = 'blue-snackbar'
): void {
if (!config) {
config = new MatSnackBarConfig();
config.duration = 3000;
config.verticalPosition = 'bottom';
config.horizontalPosition = 'end';
config.panelClass = [classOverride];
}
const sbMessage = new SnackBarMessage();
sbMessage.message = message;
sbMessage.action = action;
sbMessage.config = config;
this.messageQueue.push(sbMessage);
if (!this.isInstanceVisible) {
this.showNext();
}
}
private showNext() {
if (this.messageQueue.length === 0) {
return;
}
const message = this.messageQueue.shift();
this.isInstanceVisible = true;
this.snackBarRef = this.snackBar.open(
message.message,
message.action,
message.config
);
this.snackBarRef.afterDismissed().subscribe(() => {
this.isInstanceVisible = false;
this.showNext();
});
}
}
答案 3 :(得分:1)
您可以通过进行以下简单的更改来实现此目的:
this.snackBarService.add(['A','B','C']); // pass messages as array
add(messages: Array<string>, action?: string, config?: MdSnackBarConfig): void{
if ( !config ){
config = new MdSnackBarConfig();
config.duration = 10000;
}
let sbMessage = new SnackBarMessage();
sbMessage.message = message;
sbMessage.action = action;
sbMessage.config = config;
messages.forEach((message,index) => {
setTimeout((message) => {
sbMessage.message = message;
this.messageQueue.next(sbMessage);
},(config.duration*index);
})
}
答案 4 :(得分:1)
这是我的解决方案
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>
int main(){
int a, b, i, j,k,l;
int array1[i][j], array2[i][j];
printf("enter Matrix line number: ");
scanf("%d", &a);
printf("enter the number of Matrix columns:");
scanf("%d", &b);
int matrix[a][b], matrix2[b][a];
for(i=0; i<a; i++)
{
}
for(int i=0; i<a; i++)
for(int j=0; j<b; j++){
array1[i][j] = rand() % 10+1;
array2[i][j] = rand() % 10+1;
}
printf("\nOur matrix:\n");
for(int i=0; i<a; i++){
for(int j=0; j<b; j++){
printf("%3d ", array2[i][j]);
}
printf("\n");
}
printf("select a cell from The Matrix:\n");
printf("Senter the line of The Matrix you are selecting:\n");
scanf ("%d",&k);
printf ("enter the column of The Matrix you are selecting:\n");
scanf("%d",&l);
int p=array2[k][l];
int r=array2[k-1][l];
int m=array2[k][l-1];
int n=array2[k+1][l];
int s=array2[k][l+1];
if(p>r && p>n && p>s && p>m)
{
printf("The cell you enter is larger than all its neighbors.\n");
char S=array2[k][l];
S='R';
printf("%3d", array2[k][l]);
}
else
{
printf("The cell you enter is smaller than its neighbors and / or has a value equal to its neighbors.\n");
char S=array2[k][l];
S='G';
printf("%3d", array2[k][l]);
}
getch();
return 0;
}
答案 5 :(得分:0)
邮件列表:
messages = [
{
text: "This is message 1",
},
{
text: "This is message 2",
}
];
循环浏览它们并显示一条消息
message.forEach( (message, index) => {
setTimeout(() => {
this.snackBar.open(message.text, action, {
duration: this.timeOut,
verticalPosition: 'bottom', // 'top' | 'bottom'
horizontalPosition: 'end', //'start' | 'center' | 'end' | 'left' | 'right'
panelClass: [className],
});
}, index * (this.timeOut+500)); // 500 - timeout between two messages
});
演示:
https://www.coditty.com/code/angular-material-display-multiple-snackbars-messages-in-sequence
答案 6 :(得分:0)
面对同一问题和另一个要求,当所有snackbar
关闭时,需要通知调用函数,我终于使用递归使用了该解决方案:
调用方法:
testFunction(): void {
this.showMsgs().subscribe(() => {
// Do stuff after all messages were closed
}
}
该函数一个接一个地显示所有消息,并让调用者函数关闭所有Messenger:
showMsgs(): Observable<any> {
if (this.msgList.length) {
const msg = this.msgList.pop();
let closedEvent: Observable<any>;
// If there are other msgs they should be shown first
if (this.msgList.length) {
closedEvent = this.showMsgs().pipe(
switchMap(() => {
return this.snacBar.open(msg, 'Ok', {
verticalPosition: 'top' }).afterDismissed();
}));
} else {
// This is the only msg on the list, show it and return the close subscription
closedEvent = this.snacBar.open(msg, 'Ok', {
verticalPosition: 'top' }).afterDismissed();
}
return closedEvent;
}