2014-04-04 48 views
14

在不暴露全局變量的情況下在Angular中使用第三方庫的最佳方式是什麼?AngularJS:在不暴露全局變量的情況下使用第三方庫

舉例來說,如果我使用underscore.js,我想注入到_只使用它的控制器。

angular.module('module').controller(function(_) { 
    // _ is injected only into this scope 
}; 

爲了得到這樣的效果,我見過一些人負載腳本標記全球​​下劃線,然後創建一個像這樣的服務:

myModule.factory('_', function ($window) { 
    return $window._; 
}); 

然而,這還污染了全球範圍內與_ 。

是否有登記和注射第三方庫,而不會造成這個問題的「角辦法」?

+0

只是順便記錄,它通常建議使用注射用'$ window'而不是全球'window',允許在嘲諷試驗。 –

+0

謝謝!我剛剛編輯它使用$窗口。 –

回答

14

你不能做的第三方庫是如何寫的,除非他們分叉和創建自己的版本什麼。

第三方庫幾乎總是在全球範圍內建立這樣的變量,和你提到的角模塊中使用它們的兩種最常用的方法:通過注射$window並直接使用它們,或者通過創建一個薄service其提供對象。

,因爲它使得在其它模塊簡單的代碼,我贊成在大多數情況下後者。另外,在我看來,這種服務方法使得控制器中的代碼看起來不那麼「神奇」並且更易於調試,因爲它清楚了庫的位置,例如_來自。出現「無所不能」的變量是全局變量開始的一些問題。

圖書館將仍然是「污染」全球範圍內,除非你明確地刪除它們從全球範圍內,也許在一個服務,然後可以通過它取一個指向他們之後。但是,我看不出有這樣做的動機。任何其他嘗試,例如使用Angular服務實際下載第三方腳本並對其進行評估,以某種方式阻止其到達全局範圍,似乎極其低效,過度設計且速度慢(計算上以及與何時HTTP請求相關解僱)。

這是一個好主意,不要創建比嚴格必要的更多的全局變量。

4

Miike是對的,你不能「阻止」模塊做壞事。一旦什麼叫window.whatever = ...

Require.js雖然是酷異步模塊定義庫/方法,它可以幫助誰正在建設的包做沒有全局命名空間碴的人。它不會幫助罪犯,但它很整潔。

http://requirejs.org/

+0

如果第三方庫提供'noConflict'選項,那麼您可以使用它來從全局範圍中刪除變量(根據[我的答案](http://stackoverflow.com/a/25400627/808278))。 –

5

對於支持提供noConflict功能的第三方庫 - 如UnderscorejQuery - 你可以用它來防止全球污染的角度工廠。

myModule.factory('_', ['$window', function ($window) { 
    var underscore = $window._.noConflict(); 

    return underscore; 
}]); 

由於Angular中的所有服務都是單例,這意味着噴油器至多使用每個配方一次來創建對象。噴油器然後緩存所有未來需求的參考。

2

我創建了一個工具,它將爲支持require js的所有庫創建一個角度工廠而不是全局工廠。由於大多數庫支持require.js,因此我可以編寫一個模仿require的'define'函數的函數,但不是將庫添加到require中,而是將它添加爲角度注入。這實際上是plug n' play。只需在jQuery和angular之後添加js源代碼就可以了。它被稱爲角度全局注入器,可在github上獲得。以下是鏈接:https://github.com/btesser/angular-global-injector

5

將第三方庫放入角常量中。 保持您的代碼可讀性和清潔性,並且您可以將它們注入到特定的控制器,指令中......要使用它們的位置。

angular 
     .module('sampleApp', []) 
     .constant('_', window._) 
     .constant('$', window.$) 

正如John Papa's style guide[學分@MaximilianoBecerra]

+0

這似乎是正確的路要走,記錄在angularjs styleguide:https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#style-y240。 –

+0

@MaximilianoBecerra無法看出你是否已經完成了它,但upvoting是一個很好的方式來陳述答案的正確性。 如果我將styleguide中的鏈接添加到我的答案中,可以嗎? – tdhulster

+1

@ tdhulster我已經upvoted,我認爲是的,因爲在那裏你可以找到什麼,爲什麼和如何:)的完整參考 –

相關問題