2014-04-04 3 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

Спасибо! Я только что отредактировал его, чтобы использовать $ window. –

ответ

14

Вы не можете ничего сделать о том, как написаны библиотеки сторонних разработчиков, за исключением того, что они разворачивают их и создают вашу собственную версию.

Третьи библиотеки сторонних почти всегда создают такие переменные на глобальном масштабе, и вы упоминаете два наиболее часто используемых способов их использования в угловом модуле: путем введения $window и использовать их непосредственно, либо путем создания тонкой service, который обеспечивает объект.

Я бы предпочел последнее в большинстве случаев, потому что это упрощает код в других модулях. Кроме того, на мой взгляд, сервисный подход делает код в ваших контроллерах менее «волшебным» и более отлаживаемым, так как становится ясно, где библиотека, например. _ происходит. Переменные, появляющиеся «из воздуха», представляют собой проблему с глобальными переменными.

Библиотека по-прежнему будет «загрязнять» глобальную область видимости, если вы явно не удаляете их из глобальной области видимости, возможно, после получения указателя на них в службе, которая затем может передать ее. Однако я не вижу никакой мотивации для этого. Любые другие попытки, такие как использование Угловой службы для фактической загрузки стороннего скрипта и оценки его, каким-то образом препятствующего достижению глобальной области, кажутся весьма неэффективными, чрезмерно спроектированными и медленными (как в вычислительной, так и в том случае, когда HTTP-запросы уволен).

В противном случае не рекомендуется создавать глобальные переменные, чем это необходимо.

4

Miike прав, вы не можете «остановить» модуль от плохого состояния. Как только что-то вызывает window.whatever = ...

Require.js, хотя это классно, как библиотека/методология определения асинхронного модуля, которая помогает людям, которые создают пакеты, делать это, не сбрасывая в глобальное пространство имен. Это не поможет правонарушителям, но это здорово.

http://requirejs.org/

+0

Если сторонняя библиотека предоставляет параметр «noConflict», вы можете использовать его для удаления переменных из глобальной области (согласно [мой ответ ниже] (http://stackoverflow.com/a/25400627/808278)). –

5

Для сторонних библиотек, которые поддерживают обеспечивают noConflict функции - такие, как Underscore и jQuery - вы могли бы использовать, чтобы предотвратить глобальное загрязнение окружающей среды в вашем угловом заводе.

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

    return underscore; 
}]); 

Поскольку все услуги в угловому одноэлементны это означает, что инжектор использует каждый рецепт более одного раза, чтобы создать объект. Затем инжектор кэширует ссылку для всех будущих потребностей.

2

Я создал инструмент, который создаст угловой завод, а не глобальный для всех библиотек, которые поддерживают js. Поскольку большинство библиотек поддерживают require.js, я смог написать функцию, которая имитирует функцию «определить», но вместо того, чтобы добавлять требуемую библиотеку, она добавляет ее как угловую инъекцию. Это практически plug n' play. Просто включите источник js после jQuery и угловой, и вам хорошо идти. Он называется угловым глобальным инжектором и доступен на github. Вот ссылка: https://github.com/btesser/angular-global-injector

5

Поместить сторонние библиотеки в угловые константы. Сохраняет ваш код читаемым и чистым, и вы можете вводить их в определенные контроллеры, директивы, ... там, где вы хотите их использовать.

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

Как указано в John Papa's style guide[кредитов @MaximilianoBecerra]

+0

Кажется, что это правильный путь, задокументирован на угловом стиле: https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#style-y240. –

+0

@MaximilianoBecerra Не могу понять, было ли это уже сделано или нет, но вы можете указать правильность ответа. В порядке, если я добавлю ссылку от styleguide к моему ответу? – tdhulster

+1

@ tdhulster Я уже поддержал, и я думаю, что да, потому что там вы можете найти полное описание того, что, почему и как :) –

Смежные вопросы