Angularjs 共享指令多个实例中的数据

Angularjs 共享指令多个实例中的数据,angularjs,Angularjs,我有一个自定义指令,可以在整个应用程序中重复使用。这个指令使用了uigrid,我试图确定允许从应用程序的任何地方访问gridapi的“角度方式” 如果只是一个实例,我会使用服务在控制器之间共享数据: var attachments = angular.module('attachments', ['ui.grid']); // this would be accessible from any of my controllers attachments.factory('Attachments

我有一个自定义指令,可以在整个应用程序中重复使用。这个指令使用了
uigrid
,我试图确定允许从应用程序的任何地方访问gridapi的“角度方式”

如果只是一个实例,我会使用服务在控制器之间共享数据:

var attachments = angular.module('attachments', ['ui.grid']);

// this would be accessible from any of my controllers
attachments.factory('Attachments', function() {
    return {};
});

attachments.directive('attachments', function() {
    return {
        restrict: 'E',
        templateUrl: 'attachments.html', // template has a ui-grid, among other elements
        controller: ['$scope', 'Attachments', function($scope, Attachments) {

            $scope.gridOptions = {
                // ui-grid code here
                onRegisterApi: function( gridApi ) {
                    Attachments.grid = gridApi;
                }
            };
        }]
    };
});
但是,该指令可能有多个实例

例如,该指令可能有一个主要实例,一个在模态中,一个在侧栏中,一个在模态中,等等

我想我可以将属性名称空间添加到该服务中

Attachments = {
  libraryGrid: // ...
  someModalGrid: // ...
}
等等

我希望避免为每个可能的实例提供服务,即:

attachments.factory('SomeModalAttachments', function() {
    return {};
});
虽然它可以工作,但感觉效率低下。但是,这两种选择都比深入模式范围并使用必要的API查找子范围要好得多


还有其他方法我没有考虑吗?

对我来说,这取决于你的使用模式

如果要让多个应用程序和其他应用程序位访问它们,那么这意味着以下几点之一:

  • 访问实际上是从网格启动的。因此,您可能有许多列表页面,而当前活动的列表页面就是您要处理的页面。因此,我将拥有网格寄存器,其中包含所有它想与之交谈的内容,并在它再次关闭时取消注册。其他的都是服务(单身)

  • 这些网格有指定数量,您可以通过名称与它们交谈——因此您希望与列表页网格、模式网格或其他任何网格交互。因此,每个网格注册器都位于中央的某个位置(可能是一个其他一切都与之对话的服务)

  • 网格是辅助的。因此,一个页面包含grid指令,然后该页面想要与该网格对话。您可以将一个对象传递到指令中,然后在该对象上注册网格本身。因此,您使用“myGridCommunicationObject={}”调用该指令,然后网格执行“$scope.myGridCommunicationObject.gridApi=gridApi”。这不允许应用程序的其他部分与网格通信,但是如果您真的只希望创建网格的内容与网格通信,那么它工作得很好

  • 你可以广播。因此,如果您不关心与哪个网格对话,您只想与当前可见的任何网格对话(比如您正在调整网格大小或其他),您可以向它们广播一个事件,并且您的所有网格指令都可以侦听该事件。更进一步,您可以广播并在参数中包含网格id或名称,然后让每个网格在采取行动之前检查是否是我


  • 说了所有这些选项之后,您正在做的事情有一点代码味道。实际上,应用程序的任意部分不应该直接与网格Api通信,它们应该与保存网格的控制器上的方法通信。也许您想做的一些示例会有所帮助,但我觉得模型应该是网格注册以使用其他服务(例如调整大小通知)的模型,或者是拥有网格的控制器与网格交互的模型,以及与该控制器交互的其他模型。

    谢谢,其中一些想法值得考虑。这个应用程序是对一个已有十年历史的web应用程序的完全重写,因此调整我的思维过程是一项艰巨的工作。需要外部资源来“访问网格”的情况并不常见,但一个很好的例子是当一个侧栏面板想要以编程方式告诉网格要标记为选中的行时。非角度应用程序有一些粗糙的
    app.mainGrid.setSelectedRows()调用。也许您建议将组件(侧栏)传递到附件网格(并侦听事件)会更好?您可以将侧栏传递到网格。但是,如果主要是因为在您的控制之外有一些东西可以告诉您选择某些行,那么该东西可能也知道它要与哪些网格通信。因此,广播的想法可能更好-它调用
    app.setSelectedRows('mainGrid',row_id)
    ,该函数在内部只是广播,任何呈现的网格指令都会侦听该广播,检查请求的网格是否是它们,然后应用它,但同样的,你也可能有点笨拙,然后让每个网格在
    $rootScope
    上设置一些内容。所以
    $rootScope.grids['mainGrid']=$scope
    。然后在某个地方编写一个允许网格通信的包装器,它在内部只执行
    $rootScope.grids['mainGrid'].gridApi.dostuff
    。外部应用程序调用该包装器。使用服务可以更优雅地获得相同的效果,但$rootScope也可以。如果您使用服务路径,那么该指令包含服务,并且执行与$rootScope中相同的
    gridHandler.grids['mainGrid']=$scope
    ,但您只需使用服务即可。另外考虑这2秒钟的时间……gridHandler服务应该具有
    gridHandler.addGridScope('mainGrid',$scope)
    而不仅仅是直接写入。尽管两者都有效。