Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用服务更新2个控制器之间的共享数据_Javascript_Angularjs_Typescript_Angularjs Scope_Dom Events - Fatal编程技术网

Javascript 使用服务更新2个控制器之间的共享数据

Javascript 使用服务更新2个控制器之间的共享数据,javascript,angularjs,typescript,angularjs-scope,dom-events,Javascript,Angularjs,Typescript,Angularjs Scope,Dom Events,我有两个控制器,我想在其中共享数据。一个控制器支持一个视图,该视图包含一个经常更改其“选定项”的表,另一个控制器使用所述项信息从API获取数据。由于这两个控制器支持视图并且位于同一页上,因此它们没有经典的父/子层次结构,而是更多的“兄弟” 目前,我正在使用一个简单的“事件总线”服务,它使用$emit调用根作用域上的事件,我将其注入两个控制器中,在其中使用$rootScope.$on侦听更改。现在我多次听说这是一个糟糕的解决方案,我应该使用服务来共享数据,但是没有人真正解释如何在同样的情况下观察数

我有两个控制器,我想在其中共享数据。一个控制器支持一个视图,该视图包含一个经常更改其“选定项”的表,另一个控制器使用所述项信息从API获取数据。由于这两个控制器支持视图并且位于同一页上,因此它们没有经典的父/子层次结构,而是更多的“兄弟”

目前,我正在使用一个简单的“事件总线”服务,它使用
$emit
调用根作用域上的事件,我将其注入两个控制器中,在其中使用
$rootScope.$on
侦听更改。现在我多次听说这是一个糟糕的解决方案,我应该使用服务来共享数据,但是没有人真正解释如何在同样的情况下观察数据的变化

  • 使用
    $watch
    是错误的
  • $broadcast
    坏了
(似乎真的有一场战争,所以更应该避免哪种解决方案)

我当前的解决方案:

控制器1 控制器2 事件总线服务
使用此解决方案是否存在任何主要缺点?在更新数据等方面,“服务方式”是否更好?

您是正确的,应该避免使用
$on
$emit
,因为它们会产生不必要的噪音。对于这种情况,实际上有一个非常简单的解决方案,我经常使用它

您需要在服务中拥有一个对象,并向一个控制器提供对该对象的引用,而需要触发操作的另一个控制器可以监视服务变量(顺便说一下,TypeScript做得很好):

然后,在其作用域中包含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; 
    }
}
$scope.$watch(function(){
        return busService.myObj,itemSelected;
    }, function (newValue) {
        //do what you need
});
现在,由于在控制器2中您将注入服务,因此您将观察服务的变量:

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; 
    }
}
$scope.$watch(function(){
        return busService.myObj,itemSelected;
    }, function (newValue) {
        //do what you need
});
在更新数据等方面,“服务方式”是否更好

对。原因是,这些事件就像“向空中扔一个球,希望有人能接住它”。然而,服务是关于两个控制器如何交互的定义契约

如果您使用TypeScript,您显然关心类型安全,服务可以为您提供这一点


仅供参考,我们内部有以下指南:

控制器之间的共享信息 当屏幕高度嵌套各种占位符和它们自己的“html+控制器”时,我们需要一种在这些控制器之间共享信息(单一真实来源)的方法

1根控制器 区段的主控制器。负责公开作用域上的SharedClass实例(允许嵌套html段直接访问此模型)和任何顶级控制器函数

2共享类 角度服务,因为它很容易注入到单个控制器/指令中。包含在屏幕不同部分共享的信息/功能,例如多选模式、显示/选择的对象、用于改变这些对象的操作等

3个单独的Html+控制器
这些子用户可以使用简单的角度依赖注入请求SharedClass。控制器HTML应该自动获得对SharedClass实例的访问权(因为它是由RootController公开给scope的)。

因此,如果我正确理解$watch,我不必做任何其他事情,除了。。等待改变?没有$broadcast等吗。?包装器类的意义是什么?编辑:还有,您选择$scope.itemSelected有什么原因吗?@xvdif没错,
$watch
会更新您的更改,您不必执行
$broadcast
。我包含的包装器类是因为有时直接在作用域或服务中的原语类会出现问题,但我没有找到原因,所以我养成了观察其他对象内部变量的习惯,您不必这样做
$scope.itemSelected
我只是假设更新的是您的变量(您说所选项目经常更改)。@xvdiff我添加了此项,因为服务需要对您的变量进行引用。这样,当您更新它时,它也会在服务中得到更新,然后手表会在您的另一个控制器中触发。TS中的私有类变量不会发生这种情况吗?(可能是一个绝对的初学者问题。)@xvdiff不必是私人的,你可以公开。唯一重要的是服务和你的控制器拥有相同的引用。哇,你无处不在。就像一个有棱角的斯基特先生。非常感谢。表示负责公开共享服务的“根控制器”似乎是个好主意。谢谢你的好话:)
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; 
    }
}
$scope.$watch(function(){
        return busService.myObj,itemSelected;
    }, function (newValue) {
        //do what you need
});