Angular2在1个客户端更改后端后更新所有客户端UI



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

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

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

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

到目前为止还不错用户A自己看到UI已更新,因为对象现在已"标记"。

步骤2:用户B操作 用户B已经加载了页面,因此已经调用Get方法来填充他端的列表。但是,由于用户A已经更新了一个项目,使用者B还必须看到该特定项目现在被设置为"已标记"。然而,这并没有发生,用户B的浏览器中的列表与的用户A浏览器中的不同。

问题我如何实现此场景,以便当一个用户对对象的任何更新也被其他用户接受时?

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

编辑:我通过以下帖子实现了该功能:http://beyondscheme.com/2016/angular2-discussion-portal。然而,我想避免经常调用GET All API调用,因为它会创建大量的数据流,而这些数据流似乎是腰部的,因为我只需要一个项目。

订单信息。组件

获取

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;
}
}
})
}

订单信息.服务

获取

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);
}

感谢我在这里找到的教程: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;
}
}

最新更新