2017-11-21 3 views
1

順序で材料設計スナックバー複数のメッセージ:角度2/4 - 私は<a href="https://material.angular.io/components/snack-bar/overview" rel="nofollow noreferrer">snackbar</a>表示する「スナックバーサービス」を実施している

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

おそらく、あなたは 'afterDismissed'メソッドを利用しようとすることができますか? https://material.angular.io/components/snack-bar/api –

+0

@AamirKhanありがとう、私は成功なしで試してみました。私はどのようにメッセージのリストを消費し、前のメッセージを消した後にsnackBarを待っているのかわかりません。 – ar099968

答えて

1

タイムアウト機能を使用して別のスナックバーを開く@Aamirカーンが指摘したように - afterDismissedを使用して、私は少しのコードを微調整しています。

this.msgQueue.push(sbMessage); 
if (!this.isInstanceVisible) { 
    this.showNext(); 
} 

Plunker

注意 - -

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()の内側には、これを追加、汚いと非標準的な方法のそのようなものではなく、理想的なユーザーエクスペリエンス(IMO)私のコードにはいくつかのメモリリークがあり、フラグを使用するためにいくつかの競合状態が発生する可能性があります。

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); 
    }) 
} 
+0

返事をありがとう。複数のコンポーネントが同じサービスを使用し、複数のメッセージを追加すると、ソリューションが機能しません。より良い方法は、サービスがメッセージのリストを消費することができるようにすることです。 – ar099968

2

あなたが方法を、時間を使用する必要があります。特定の時間内 皮スナックバーと

constructor(public snackBarService: SnackBarService) { 
      this.snackBarService.add('A') 
      setTimeout(this.snackBarService.add('B'),10000); 
      setTimeout(this.snackBarService.add('C'),20000); 
     } 
+0

返事をありがとう。複数のコンポーネントが同じサービスを使用していて、新しいメッセージの追加を待つ時間を知らずに複数のメッセージを追加した場合、ソリューションは機能しません。より良い方法は、サービスがメッセージのリストを消費することができるようにすることです。 – ar099968

関連する問題

 関連する問題