2016-07-21 6 views
1

Es gibt einen websocket Echo-Dienst, die Nachrichten senden und empfängt eine beobachtbare der ungelesenen Nachrichten zu erstellen:Wie aus den beobachtbaren aller Nachrichten

@Injectable() 
export class NotificationsService { 
    private ws = new $WebSocket('wss://echo.websocket.org'); 

    wsSendMessage(message: string = `Message ${Math.random()}`): void { 
    this.ws.send(message); 
    } 

    wsGetMessages(): Observable<string> { 
    return Observable.from(this.ws.getDataStream()) 
     .map((res: any) => res.data); 
    } 
} 

Benachrichtigungen Komponente abonniert diese beobachtbaren und zeigt alle Nachrichten in der Meldung Dropdown-Panel:

getMessages(): void { 
    this.notificationsService.wsGetMessages().subscribe(
     (message: string) => { 
      this.messages.unshift(message); 
     }, 
     (err: any) => console.log(err) 
    );  
    } 

ich brauche die Anzahl der ungelesenen Nachrichten in der navbar Komponente zu zeigen, und setzen sie sich auf 0, wenn der Benachrichtigung Drop-Down-Panel geöffnet wird. Und ich habe keine Ideen, wie es geht, also brauche ich deine Hilfe ...

P.S.

Jetzt WebSocket Echo-Service ist:

@Injectable() 
export class NotificationsService { 
    private ws = new $WebSocket('wss://echo.websocket.org'); 

    wsSendMessage(message: string = `Message ${Math.random()}`): void { 
    this.ws.send(message); 
    } 

    wsGetMessages(): Observable<Object> { 
    return Observable.from(this.ws.getDataStream()) 
     .map((res: any) => res.data); 
    } 

    messagesReadStream(msgArray: Object[]): Observable<Object> { 
    return Observable.from(msgArray); 
    } 
} 

und Benachrichtigungen Komponente ist:

export class Notifications implements OnInit { 
    messagesAll:string[] = []; 
    messagesRead:string[] = []; 
    newMessagesNumber:number = 0; 

    constructor(private notificationsService: NotificationsService) { 
    } 

    addMessage(): void { 
    this.notificationsService.wsSendMessage(); 
    } 

    getMessages(): void { 
    this.notificationsService.wsGetMessages() 
     .subscribe(
     (message: any) => this.messagesAll.unshift(message), 
     (err: any) => console.error(err) 
    ); 
    } 

    readMessages(): void { 
    this.messagesRead = this.messagesAll.slice(); 

    this.notificationsService.messagesReadStream(this.messagesRead) 
     .switchMap(() => 
     this.notificationsService 
      .wsGetMessages() 
      .scan((unread, _) => unread + 1, 0)  
      .startWith(0)) 
     .subscribe(
     (count: number) => this.newMessagesNumber = count, 
     (err: any) => console.error(err) 
    );  
    } 

    ngOnInit(): void { 
    this.getMessages(); 
    } 
} 

mit Vorlage:

<button type="button" class="btn btn-primary-outline btn-sm" (click) = "addMessage()"> 
    Add message 
</button> 

<button type="button" class="btn btn-primary-outline btn-sm" (click) = "readMessages()"> 
    Read messages 
</button> 

<div style="margin-top: 1rem"> 
    <span class="circle bg-warning fw-bold"> 
     {{newMessagesNumber}} 
    </span> 
</div> 

Und jetzt, wenn ich auf button 'Add message' mein Zähler doesn‘ t Ändern Sie den Wert von 0. Und nur wenn ich auf button 'Add message' klicke, dann klicke auf button 'Read messages' und klicke dann auf button 'Add message', wieder startet der Zähler gut. Kannst du erklären, was das Problem ist?

+0

Welcher Teil funktioniert nicht? – paulpdaniels

+0

wsGetMessages() gibt ein Observable mit allen Nachrichten vom Websocket-Server zurück. Und ich muss die Anzahl der ungelesenen Nachrichten anzeigen. Es ist dasselbe, bevor ich das Benachrichtigungsfeld öffne. Aber danach müssen nur neue Nachrichten gezählt werden. Ich denke, es wäre eine weitere beobachtbare mit allen gelesenen Nachrichten. Aber wie erstelle ich es ??? – daslashi

Antwort

2

Sie benötigen mehr als eine Observable. Eine, um die Zählung zu enthalten und eine, um zu signalisieren, wenn Nachrichten gelesen wurden. Ersteres wird den Stream wsGetMessage verwenden, während letzterer mit einem Observable verbunden werden muss, das immer dann ausgelöst wird, wenn das Benachrichtigungsfeld geöffnet wird.

const panelOpened: Observable<any> = //..Need a signalling mechanism for when the messages get read 

const unreadCount: Observable<number> = messagesRead.switchMap(() => 
    this.notificationsService 
     .wsGetMessages() 
     //Just count all of the messages as they come in. 
     .scan((unread, _) => unread + 1, 0) 
     //Make sure it always gets reset to zero 
     .startWith(0)); 

//Subscribe to updates on count changes. 
unreadCount.subscribe(count => this.unreadMessageCount = count); 
+0

Ich habe meinen Code aufgrund Ihrer Empfehlungen aktualisiert, habe aber immer noch ein Problem. Kannst du damit helfen? – daslashi

Verwandte Themen