2015-04-14 46 views
0

我有一個自定義指令,可在整個應用程序中重複使用。此指令使用ui-grid,我試圖確定允許從應用程序的任何位置訪問網格API的「角度方式」。從指令的多個實例共享數據

如果這只是一個例子,我會使用一個服務在控制器之間共享數據:

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查找子範圍要好得多。

有沒有其他方法我沒有考慮過?

回答

0

對我而言,這取決於您的使用模式。

如果你想擁有這些與應用程序的其他位去訪問它們的倍數,那麼這意味着幾件事情之一:

  1. 訪問實際上是從電網啓動。所以你可能有很多列表頁面,而當前活動的列表頁面就是你想要處理的列表頁面。所以我會在網格中註冊所有想要聊天的內容,並在關閉時重新註冊。其他的東西都是服務(單身人士)。

  2. 這些網格中有一定數量的網格,您可以通過名稱與它們交談 - 因此您想要與列表頁面網格或模式網格等進行交互。因此,您將每個網格寄存器放置在某個中央位置(也許是其他所有服務都可以使用的服務)。

  3. 網格是東西的附屬物。因此,一個頁面包含網格指令,然後該網頁想要與該網格進行交談。您可以將一個對象傳遞給該指令,然後讓該網格註冊該對象。所以你用「myGridCommunicationObject = {}」調用指令,然後網格執行「$ scope.myGridCommunicationObject.gridApi = gridApi」。這不會讓應用程序的其他部分與網格對話,但如果真的只需要創建網格來與之交談,那麼它就可以很好地工作。

  4. 您可以播放。因此,如果您不關心與您交談的網格,您只想與任何當前可見的網格(例如您正在調整它們的大小)進行對話,您只需向其發送一個事件,並且所有的網格指令都可以聽聽那個事件。更進一步,您可以在參數中廣播幷包含網格ID或名稱,然後讓每個網格在採取行動之前檢查是否是我。

說了所有這些選項之後,有一些關於你正在做的事情有點代碼味道。真的,應用程序的任意位不應該直接與網格Api對話,它們應該與控制器上的方法進行通信,該方法持有網格。也許你想做什麼的一些例子會有所幫助,但是我覺得模型應該是註冊使用其他服務(例如調整大小通知)的網格之一,或者擁有網格與網格交互的控制器,和其他與該控制器交互的東西。

+0

謝謝,其中一些想法值得考慮。這個應用程序是一個從十年前的Web應用程序完全重寫,所以調整我的思維過程是一個工作。對「訪問網格」的外部資源的需求不會非常普遍,但是一個很好的例子是當側邊欄面板想要以編程方式告訴網格哪些行要選擇標記時。非角度的應用程序有一些cruddy'app.mainGrid.setSelectedRows()'調用。也許你建議將組件(邊欄)傳遞給附件網格(並且聽一個事件)會更好嗎? – helion3

+0

您可以將邊欄傳遞給網格。但是如果大多數情況下有一些事情可以讓你選擇某些行,那麼大概也知道它想要與哪個網格進行通信。所以也許廣播的想法是更好的 - 它調用app.setSelectedRows('mainGrid',row_ids)'並且該函數在內部只是廣播,所有呈現的網格指令都會監聽該廣播,檢查請求的網格是否他們,然後應用它 – PaulL

+0

但同樣,你可能只是有點bodgy,只是讓每個網格設置'$ rootScope'上的東西。所以'$ rootScope.grids ['mainGrid'] = $ scope'。然後你在一個允許網格通信的地方編寫一個包裝器,它在內部就是'$ rootScope.grids ['mainGrid']。gridApi.dostuff'。外部應用程序調用該包裝器。您可以使用服務更優雅地獲得相同的效果,但$ rootScope也可以。如果你走的是服務路線,那麼這個指令包含了服務,並且和$ rootScope中的'gridHandler.grids ['mainGrid'] = $ scope'一樣,但你只需要使用服務。 – PaulL