从 signalR 更新后如何重新加载我的表

Posted

技术标签:

【中文标题】从 signalR 更新后如何重新加载我的表【英文标题】:How can I reload my table after an update from signalR 【发布时间】:2020-04-13 09:18:25 【问题描述】:

美好的一天!,

我是 angular 和 signalR 的新手,我想要实现的是,在收到来自 signalR 的消息后刷新表格。我已经确认可以收到消息,但问题是我需要重新加载表格。所以我所做的是,在收到来自 order.component 的消息后,我调用了 loadData。不幸的是没有运气。 收到来自 signalR 的更新后,如何重新加载我的表。

下面是我的 order.component.ts。

import  Component, Injectable  from '@angular/core';
import  HttpClient, HttpHeaders  from '@angular/common/http';

@Component(
  selector: 'app-orders',
  templateUrl: './orders.component.html'
)

@Injectable()
export class OrdersComponent 
  private orders : IOrder[];
  private products: IProduct[];
  private cart: any[] = [];
  private orderNumber: string;

  constructor(private http: HttpClient) 

    http.get<IOrder[]>('http://localhost:63754/api/v1/order/1').subscribe(result => 
      this.orders = result;
    , error => console.error(error));
  

  public loadData(http: HttpClient) 
    http.get<IOrder[]>('http://localhost:63754/api/v1/order/1').subscribe(result => 
      this.orders = result;
    , error => console.error(error));


  

  public onSelect(selectedItem: any) 

    this.http.get<IProduct[]>('http://localhost:63754/api/v1/product/list').subscribe(result => 
      this.products = result;
    , error => console.error(error));

    this.orderNumber = selectedItem.orderNumber;
  

  public onSelectUpdate(selectedItem: any) 

    this.cart.forEach((value, index, array) => 

      if (value.productId === selectedItem.productId) 
        array.splice(index, 1);
      

    );


    this.cart.push(selectedItem);
  

  public submit() 

    let request: any = 
      orderNumber: this.orderNumber,
      customerId: 1,
      products: this.cart
    ;


    this.http.put('http://localhost:63754/api/v1/order/update', JSON.stringify(request),
      
        headers: new HttpHeaders(
          'Content-Type': 'application/json'
        )
      ).subscribe(result => 
      //do nothing
    , error => console.error(error));

    this.cart = [];
    this.products = null;
  


interface IOrder 
  orderId: number;
  customerId: number;
  orderNumber: string;
  orders: any[];
  orderDate: any;
  isProcessed: boolean;


interface IProduct 
  productId: number;
  name: string;
  description: string;
  quantity: number;

下面是我的 app.component.ts。

import  Component  from '@angular/core';
import  OrdersComponent  from './orders/orders.component';
import  HttpClient, HttpHeaders  from '@angular/common/http';

import * as signalR from '@aspnet/signalr';

@Component(
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  providers: [OrdersComponent]
)


export class AppComponent  
  title = 'app';

  constructor(private order: OrdersComponent, private http: HttpClient)  

  ngOnInit(): void 
    const connection = new signalR.HubConnectionBuilder().configureLogging(signalR.LogLevel.Information)
      .withUrl("http://localhost:50772/notify")
      .build();

    connection.start().then(function () 
      console.log('Connected!');
    ).catch(function (err) 
      return console.error(err.toString());
    );

    connection.on("BroadcastMessage", (type: string, payload: string) => 
      alert('received'); 
      this.order.loadData(this.http); //<-- problem
    );
  

我的 HTML。

<table class='table table-striped' *ngIf="orders">
  <thead>
    <tr>
      <th></th>
      <th>OrderNumber</th>
      <th>OrderDate</th>
      <th>Orders</th>
      <th>IsProcessed</th>
    </tr>
  </thead>
  <tbody>
    <tr *ngFor="let order of orders">
      <td>
        <button type="button" (click)="onSelect(order)" style="margin:5px;" class="btn btn-info">Modify</button>
        <button type="button" (click)="onSelect(order)" style="margin:5px;" class="btn btn-danger">Cancel</button>
      </td>

      <td> order.orderNumber </td>
      <td> order.orderDate </td>
      <td>
        <div *ngFor="let c of order.orders">
          <label> c.quantity </label> - <label> c.name </label>
        </div>
      </td>
      <td> order.isProcessed </td>
    </tr>
  </tbody>
</table>

【问题讨论】:

你可以尝试将this.order.loadData(this.http);包裹在NgZone.run 【参考方案1】:

您的问题出在connection.on。您正在接收类型和有效负载,然后将 this.http 数据传递给您的方法。因此,您需要映射接收到的有效载荷,或者如果接收到的有效载荷是表类型,则直接传递它。

connection.on("BroadcastMessage", (type: string, payload: string) => 
      alert('received'); 
      this.yourHtmlType = this.mapToMyType(payload);
      this.order.loadData(this.this.yourHtmlType);
    );

connection.on("BroadcastMessage", (type: string, payload: string) => 
      alert('received'); 
      this.order.loadData(this.payload);
    );

【讨论】:

以上是关于从 signalR 更新后如何重新加载我的表的主要内容,如果未能解决你的问题,请参考以下文章

(C#)SignalR 2.2.2 - 项目从VS(2017年以下)转移到VS 2017的问题

如何在不重新加载页面的情况下更新从 firestore 检索到的标记在我的地图上?

警告 Swift 后重新加载表

如何重新加载 UIView

检测来自客户端的SignalR中丢失的连接

在Angular Js中重新加载后,如何将复选框(选中或未选中)从javascript控制器更新到html页面?