Angular2在后端更改1个客户端

时间:2017-11-13 10:04:02

标签: angular asp.net-web-api angular2-services

我有一个与c#WebApi通信的Angular2应用程序。在加载时,我进行GET调用以检索对象列表,将它们订阅到数组并使用ng2-smart-table显示列表。我的应用程序适用于单个用户而没有任何问题,但是当我添加更多站点用户时,我没有得到正确的行为。

根据登录的用户类型,我显示2个不同的视图,两个视图使用相同的组件,因此可以访问相同的列表。用户的角色类型确定他/她可以更改哪些参数。

想象一下以下场景: 我有2个用户; 用户A 用户B 。两者都在不同的浏览器选项卡/窗口中登录,具有不同的角色类型并查看2个不同的视图。

第1步:用户A操作 在加载网页时,用户A 的浏览器调用Get方法来填充其屏幕上显示的列表。 用户A 然后单击列表中某个对象的“标记”按钮,这会在该对象的后端中将布尔属性设置为True。然后将更新的对象发送回前端并在列表中更新。

到目前为止一切顺利。 用户A 自己看到UI已更新,因为该对象现在已“标记”。

第2步:用户B操作 用户B 已经加载了页面,因此已经调用了Get方法来填充他的结尾列表。但是,由于用户A 已更新项目,用户B 也必须看到该特定项目现在设置为“已标记”。但是,这不会发生, User B 的浏览器中的列表与 User A 的浏览器中的列表不同。

问题 如何实现此方案,以便当1个用户对对象的任何更新也在其他用户之前时?

其他信息: 编辑对象的所有api调用都会返回已编辑的对象,如下例所示。

修改:我可以按照以下帖子实施该功能:http://beyondscheme.com/2016/angular2-discussion-portal。但是我想避免不断调用GET All API调用,因为它会创建看似腰部的大量数据流,因为我需要的只是1项。

阶information.component

GET

ngOnInit() {
    this.orderInformationAddEditList = new LocalDataSource();
    this.orderInformationListDataSource = new LocalDataSource();
    if (this.AuthService.isLoggedIn()) {
      this.OrderInformationService.getAll().subscribe(orderInfo => {
        this.orderInformationList = orderInfo;
        this.orderInformationListDataSource.load(this.orderInformationList);
        //this.NotificationsService.success("Success", "Loaded all items.", { timeOut: 2000, clickToClose: true, showProgressBar: true });
        console.log("Loaded all items");

        if (!this.AuthService.hasRole("desk")) {
          this.userIsDesk = false;
        }
      },
        e => {
          console.log("Error: " + e);
          if (e.status == 0) {
            this.NotificationsService.error("Error", "Unable to connect to API", { timeOut: 0, clickToClose: true });
          }
          if (e.status == 500) {
            console.log(e.json().data);
            this.NotificationsService.error(e.json().data.Name, e.json().data.Message, { timeOut: 0, clickToClose: true });
          }
        })
    } else {
      this.router.navigate(['']);      
    }
  }

标记

markOrderInformation(id: number, event: any) {
this.apiAttempts++;

this.OrderInformationService.markOrderInformation(id).subscribe(orderInfo => {
  console.log("Marked: " + orderInfo.id);
  this.NotificationsService.success("Success", "Marked: " + orderInfo.id, { timeOut: 2000, clickToClose: true, showProgressBar: true });
  this.updateOrderList(orderInfo, false);
  event.confirm.resolve(orderInfo);
  this.apiAttempts = 0;

},
  e => {
    var data = e.json();
    if (e.status == 0) {
      this.NotificationsService.error("Error", "Unable to connect to API. Please try again later..", { timeOut: 0, clickToClose: true });
    }
    if (e.status == 401) {
      this.NotificationsService.error(data.Name, data.message, { timeOut: 0, clickToClose: true });
    }
    if (e.status == 500) {
      if (this.apiAttempts < 4) {
        this.NotificationsService.error("Error", "Verify your input and try again. Attempts: " + this.apiAttempts, { timeOut: 0, clickToClose: true });
      } else {
        this.NotificationsService.error(data.Name, data.Message, { timeOut: 0, clickToClose: true });
        this.apiAttempts = 0;
      }
    }
  })
}

阶information.service

GET

  getAll(): Observable<OrderInformation[]> {
    return this.http.get(`${this.baseUrl}`, new RequestOptions({ headers: this.getAuthorizationHeaders() }))
    .map(mapOrderInformationList);
  }

标记

  markOrderInformation(id: number) {
    return this.http.put(`${this.baseUrl}/` + id + `/mark`, { 
    },
    { headers: this.getAuthorizationHeaders() })
    .map(mapOrderInformation);
  }

1 个答案:

答案 0 :(得分:0)

感谢我在这里找到的教程:http://beyondscheme.com/2016/angular2-discussion-portal,我能够每5秒发送一次GET请求。然而,这是非常昂贵的,因为我在网上发送了大量数据。

我通过返回一个包含最近编辑过的对象的较小列表来修复此问题。我这样做是通过向我的Sql实体添加一个名为lastUpdated的新DateTime列。现在每当我更新一个对象时,我都会将lastUpdated属性更改为DateTime.Now()。

最后我在Api中创建了一个名为GetUpdatedList的新GET请求方法,该方法返回在特定时间范围内更新的所有项目,我花了3分钟因为我不确定延迟有多大但我认为1分钟绰绰有余。然后,从Api接收的列表将被解析并编辑到Angular2中的现有数组中。

public List<Object> GetUpdatedList() {
 try {
    DateTime now = DateTime.Now;
    DateTime before = now.AddMinutes(-3);
    return context.Xdock_controle.Where(order => order.lastUpdated != null && order.lastUpdated <= now && order.lastUpdated >= before).ToList();
 } catch (Exception ex) {
    Logger.log(ex.Message);
    throw ex;
 }
}