Angular Mat-Table [dataSource] странное поведение, данные не загружаются после трех страниц навигации - PullRequest
0 голосов
/ 06 апреля 2020

Просто для некоторого контекста у меня есть следующее:

Внутренняя служба (Kotlin), которая генерирует поток данных:

    @GetMapping(value = ["api/v2/stocks"], produces = [MediaType.TEXT_EVENT_STREAM_VALUE])
    fun fromMongo(): Flux<MutableList<Stock>> {
        return Flux.interval(Duration.ZERO, Duration.ofSeconds(5))
                .flatMap { stockService.getAllStocks().collectList() }

    }

Служба angular для обработки сервера отправленные события:

export class StockService {

  uri = 'http://localhost:8081';

  stocks: Observable<Stock>

  constructor(private http: HttpClient, private sseService: SseServiceService, private zone: NgZone) { }

  getStocks(): Observable<Stock> {
      return this.http.get<Stock>(`${this.uri}/api/v2/stocks`)
    }

  getStocksSSE(): Observable<Stock> {
    return Observable.create(observer => {
      const eventSource = this.sseService.getEventSource(`${this.uri}/api/v2/stocks`);

      eventSource.onmessage = event => {
        this.zone.run(() => {
          observer.next(JSON.parse(event.data));
        });
      }

      eventSource.onerror = error => {
        this.zone.run(() => {
          console.log(error)
          observer.error(error);
        })
      }
    });
  }

  getStockBySymbol(symbol: string): Observable<Stock> {
    return Observable.create(observer => {
      const eventSource = this.sseService.getEventSource(`${this.uri}/api/v2/stocks/${symbol}`);

      eventSource.onmessage = event => {
      this.zone.run(() => {
        observer.next(JSON.parse(event.data));
      })
    }
      eventSource.onerror = error => {
        this.zone.run(() => {
          observer.error(error);
        })
      }
    });
  }

Наконец, компонент для отображения полученных данных:

export class StockListComponent implements OnInit {

  stocks: Observable<Stock>
  displayedColumns: String[] = ['symbol', 'name', 'value', 'gains', 'details', 'buy'];

  constructor(private router: Router,
      private stockService: StockService) {}

  ngOnInit(): void {
    this.stocks = this.stockService.getStocksSSE();
  }
}

Связанный компонент. html:

<mat-card>
<div class="mat-table-data">
    <table mat-table #table [dataSource]="stocks" aria-label="Stocks">

        <ng-container matColumnDef="symbol">
            <th mat-header-cell *matHeaderCellDef mat-sort-header>Symbol</th>
            <td mat-cell *matCellDef="let row">{{row.symbol}}</td>
        </ng-container>

        <ng-container matColumnDef="name">
            <th mat-header-cell *matHeaderCellDef mat-sort-header>Name</th>
            <td mat-cell *matCellDef="let row">{{row.name}}</td>
        </ng-container>

        <ng-container matColumnDef="value">
            <th mat-header-cell *matHeaderCellDef mat-sort-header>Share Price</th>
            <td mat-cell *matCellDef="let row">£ {{row.value}}</td>
        </ng-container>

        <ng-container matColumnDef="gains">
            <th mat-header-cell *matHeaderCellDef mat-sort-header>Change</th>
            <td mat-cell *matCellDef="let row">
            <div class="green" *ngIf="row.isPositive==true">
                +{{row.gains}}
              </div>
              <div class="red" *ngIf="row.isPositive==false">
                {{row.gains}}
              </div>
            </td>
        </ng-container>

        <ng-container matColumnDef="details">
            <th mat-header-cell *matHeaderCellDef>See More</th>
            <td mat-cell *matCellDef="let element">
              <button mat-button routerLink="/stocks/{{element.symbol}}">Details</button>
            </td>
         </ng-container>

         <ng-container matColumnDef="buy">
            <th mat-header-cell *matHeaderCellDef>Purchase</th>
            <td mat-cell *matCellDef="let element">
              <button mat-button routerLink="/stocks/{{element.symbol}}">Buy</button>
            </td>
         </ng-container>

        <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
        <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
    </table>

</div>
</mat-card>

Странное поведение, которое я вижу, состоит в том, что если я перемещаюсь между компонентами три раза (всегда конкретно три) и возвращаюсь к компоненту, где можно увидеть список акций, данные не загружаются в таблицу angular. Следует отметить, что до этого все работало, как и ожидалось, и, во-вторых, если бы я был console.log(observer.next(JSON.parse(event.data))); в сервисе, я все равно видел все данные в консоли, как и ожидалось. Это приводит меня к мысли, что проблема лежит где-то с ng-dataSource.

Открыто для всех предложений!

...