使用服务更新 2 个控制器之间的共享数据
Update shared data between 2 controllers with services
我有 2 个控制器,我想在它们之间共享数据。一个控制器支持带有表的视图,该表经常更改其"选定项",另一个控制器使用所述项信息从 API 获取数据。由于这两个控制器支持视图并且位于同一页面上,因此它们没有经典的父/子层次结构,而是更多的"同级"。
目前,我正在使用一个简单的"事件总线"服务,该服务使用我在两个控制器中注入的$emit
在根作用域上调用事件,其中使用 $rootScope.$on
侦听更改。现在我听说很多次这是一个糟糕的解决方案,我应该使用服务来共享数据,但没有人真正解释如何监视数据的变化,当也
- 使用
$watch
是不好的 -
$broadcast
不好
(似乎真的有一场关于 SO 的战争,应该更多地避免解决方案)。
我目前的解决方案:
控制器1
export class Controller1 {
private eventBus : Components.IEventBusService;
constructor(eventBus: Components.IEventBusService) {
this.eventBus = eventBus;
}
void itemSelected(item : IItemModel) {
this.eventBus.emit("itemSelected", { "item" : item });
}
}
控制器 2
export class Controller2 {
constructor($scope : ng.IScope,
eventBus : Components.IEventBusService) {
eventBus.on("itemSelected", (event, data) =>
this.onItemSelected(data), $scope);
}
private onItemSelected(data: any) {
// do something with data.item!
}
}
事件巴士服务
export interface IEventBusService {
on(event, callback, scope): void;
emit(event, data): void;
}
class EventBusService implements IEventBusService {
private rootScope: ng.IRootScopeService;
constructor($rootScope: ng.IRootScopeService) {
this.rootScope = $rootScope;
}
on(event, callback, scope) : void {
var unbind = this.rootScope.$on(event, callback);
if(scope) {
scope.$on("$destroy", unbind);
}
}
emit(event, data) : void {
data = data || {};
this.rootScope.$emit(event, data);
}
}
使用此解决方案有什么主要缺点吗?在更新数据等方面,"服务方式"是否更好?
你是对的,应该避免$on
和$emit
,因为它们会产生不必要的噪音。这种情况实际上有一个非常简单的解决方案,我经常使用它。
你需要的是服务中的一个对象,并为一个控制器提供对它的引用,另一个需要触发操作的控制器可以监视服务变量(顺便说一下,TypeScript 上做得很好):
class ItemSelectionWrapper { //just a wrapper, you could have other variables in here if you want
itemSelected: IItemModel;
}
class EventBusService implements IEventBusService {
private myObj: ItemSelectionWrapper;
...
}
然后在其作用域中包含 itemSelected 的控制器中(假设控制器 1),您引用相同的变量:
export class Controller1 {
private eventBus : Components.IEventBusService;
constructor(eventBus: Components.IEventBusService) {
this.eventBus = eventBus;
this.eventBus.myObj = this.eventBus.myObj || {};
this.eventBus.myObj.itemSelected = $scope.itemSelected;
}
}
现在,由于在控制器 2 中您将注入服务,因此您将观察服务的变量:
$scope.$watch(function(){
return busService.myObj,itemSelected;
}, function (newValue) {
//do what you need
});
在更新数据等方面,"服务方式"是否更好?
是的。原因是事件就像"向空中扔一个球,希望有人接住它"。而服务是关于两个控制器如何交互的定义契约。
如果你使用TypeScript,你显然关心类型安全,服务可以给你。
仅供参考,我们在内部有以下指导:
控制器之间共享信息
当屏幕高度嵌套着具有自己的"html +控制器"的各种占位符时,我们需要一种在这些控制器之间共享信息(单一事实来源)的方法。
1 根控制器
该部分的主控制器。负责在作用域上公开 SharedClass 实例(允许嵌套的 html 段直接访问此模型)和任何顶级控制器函数。
2 共享类
一种角度服务,因为它可以很容易地注入到单个控制器/指令中。包含在屏幕的各个部分中共享的信息/功能,例如多选模式,显示/选定对象,用于更改这些对象的操作等。
3 个单独的 HTML + 控制器
这些子控制器可以使用简单的角度依赖注入来请求共享类。控制器 HTML 应该自动访问 SharedClass 实例(因为 RootController 会向范围公开该实例)。
- 在索引.html和应用.js [node.js] 之间共享变量
- Node.js上的WebSocket,并在所有连接的客户端之间共享消息
- 使用服务(AngularJS)在控制器之间共享数据
- AngularJS中的页面之间共享数据返回空
- 是否可以缓存可下载的文件,并在XHR和非XHR请求之间共享该缓存
- 在Knockoutjs中的ViewModels之间共享变量状态
- 通过共享服务在两个不同ng应用程序中的控制器之间共享数据
- Node.js服务器和浏览器之间共享二进制缓冲区
- 使用Angularjs在两个不同页面的控制器之间共享数据
- 在两个浏览器选项卡之间共享变量范围
- 不同进程之间共享Node.js环境
- 在Angular Bootstrap Modal和父控制器之间共享作用域
- 2ng控制器,并且需要在控制器之间共享数据
- Javascript创建函数,以便在其他函数之间共享变量
- 在控制器angular js之间共享数据
- 在javascript客户端和java服务器之间共享Google Analytics ClientID
- 如何将json文件中的数据提取到对象数组中,并在两个控制器之间共享
- Angular 2,在没有直接关系的两个组件之间共享一个对象
- 在angularJS中使用模态窗口时,在控制器之间共享对象数组
- 在角度上不同控制器之间共享状态