Обновление представления с данными из веб-сокета - Angular 5

У меня есть страница, которая получает массив данных о загрузке страницы и отображает его с помощью директивы *ngFor. Также существует соединение с веб-сокетом для получения обновленных данных. В этом примере это расписание морских прогулок. Моя проблема в том, что я не знаю, как обновить данные загрузки страницы новыми данными из WS. Пока у меня есть этот код:

timeTableService.service.ts - сервис для получения исходных данных о загрузке страницы

import { Injectable } from '@angular/core';
import { ApiService } from './api.service';

@Injectable()
export class TimeTableService {

    constructor(
        private apiService: ApiService,
    ) { }

    getInitialTimes() {
        return this.apiService.get('/timetable/')
    }
}

liveTimeTableService.service.ts - сервис для подключения дескриптора подключения к веб-сокету с использованием эта библиотека

import { Injectable } from '@angular/core'
import { QueueingSubject } from 'queueing-subject'
import { Observable } from 'rxjs/Observable'
import websocketConnect from 'rxjs-websockets'
import 'rxjs/add/operator/share'

@Injectable()
export class LiveTimeTableService {
    private inputStream: QueueingSubject<any>
    public messages: Observable<any>

    public connect() {
        this.messages = websocketConnect(
            'ws://www.timetables.com:8080',
            this.inputStream = new QueueingSubject<string>() 
        ).messages.share()
    }
    public send(message: string):void {
        this.inputStream.next(message)
    }
}

timeTable.component.ts - компонент для отображения расписания

import { Component, OnInit } from '@angular/core';
import { TimeTableService, LiveTimeTableService } from './shared';
import { Subscription } from 'rxjs/Subscription'

@Component({
    selector: 'app-time-table',
    templateUrl: './time-table.component.html',
})

export class TimeTableComponent implements OnInit {
    private timeTable: any;
    private socketSubscription: Subscription

    constructor(
        private timeTableService: TimeTableService,
        private liveTimeTableService: LiveTimeTableService,
    ) {}

    ngOnInit() {
        this.liveTimeTableService.connect();
        this.liveTimeTableService.send('SUBSCRIBE times')

        // subscribe to any message updates
        this.socketSubscription = this.liveTimeTableService.messages
            .subscribe((timesUpdate) => {
                this.timeTable = timesUpdate;
        })

        // get the time table data on page load
        this.timeTableService.getInitialTimes()
            .subscribe((timeTable) => {
                this.timeTable = timeTable
        })
    }

    ngOnDestroy() {
        this.socketSubscription.unsubscribe()
    }
}

HTML-шаблон

<div *ngFor = "let boat of timeTable">
    {{ boat.name }}
    <span *ngFor = "let time of boat.times">{{time}}</span>
</ldiv>

И данные выглядит так

Данные о загрузке страницы

Данные сообщения WS (содержит незначительные обновления, такие как время и статус):

Проблема в том, что this.timeTable сбрасывается каждый раз, когда приходит новое сообщение от WS, и вся директива *ngFor запускается снова и перестраивает dom. Я хотел обновить любое выражение «время» в *ngFor новыми значениями из сообщения WS, а затем применить класс css для уведомления пользователей об изменении:

Обновление представления с данными из веб-сокета - Angular 5

Буду очень признателен за любые советы или предложения, как я могу активировать это. И извинения за очень длинный пост!

Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
0
0
1 207
1

Ответы 1

Возможно, используя параметр trackBy, как в этом ответе:

Angular 2 - с ngFor можно ли обновлять значения без перестройки dom?

Итак, ваш код будет примерно таким:

Вид:

<div *ngFor = "let boat of timeTable; let i = index; trackBy: trackByFn">
    {{ boat.name }}
    <span *ngFor = "let time of boat.times">{{time}}</span>
</div>

Составная часть

trackByFn(index, item) {
  return index;
}

В качестве справки вы должны использовать: https://angular.io/guide/template-syntax#ngfor-with-trackby

Другие вопросы по теме