Я хотел бы добавить некоторые служебные функции в мое приложение AngularJS. Например:
$scope.isNotString = function (str) {
return (typeof str !== "string");
}
Это лучший способ сделать это, чтобы добавить их в качестве службы? Из того, что я прочитал, я могу сделать это, но затем я хотел бы использовать их на своих HTML-страницах, так что все еще возможно, если они находятся в службе? Например, я могу использовать следующее:
<button data-ng-click="doSomething()"
data-ng-disabled="isNotString(abc)">Do Something
</button>
Может кто-нибудь дать мне пример того, как я мог бы добавить это. Должен ли я создать сервис или есть какой-то другой способ сделать это. Самое главное, чтобы эти служебные функции были в файле, а не в сочетании с другой частью основной настройки.
Я понимаю, что есть несколько решений, но ни одно из них не так ясно.
Решение 1 - Предложено Urban
$scope.doSomething = ServiceName.functionName;
Проблема в том, что у меня 20 функций и десять контроллеров. Если бы я сделал это, это означало бы добавление большого количества кода для каждого контроллера.
Решение 2 - предложено мной
var factory = {
Setup: function ($scope) {
$scope.isNotString = function (str) {
return (typeof str !== "string");
}
Недостатком этого является то, что при запуске каждого контроллера у меня будет один или несколько из этих вызовов установки для каждой службы, которая прошла область $.
Решение 3 - Предложено Urban
Городское решение по созданию универсального сервиса выглядит хорошо. Вот моя основная установка:
var app = angular
.module('app', ['ngAnimate', 'ui.router', 'admin', 'home', 'questions', 'ngResource', 'LocalStorageModule'])
.config(['$locationProvider', '$sceProvider', '$stateProvider',
function ($locationProvider, $sceProvider, $stateProvider) {
$sceProvider.enabled(false);
$locationProvider.html5Mode(true);
Должен ли я добавить общий сервис к этому и как я могу это сделать?
Ответы:
РЕДАКТИРОВАТЬ 7/1/15:
Я написал этот ответ довольно давно и не слишком долго следил за углом, но кажется, что этот ответ все еще относительно популярен, поэтому я хотел бы отметить, что пара моментов @nicolas делает ниже хороши. Например, добавление $ rootScope и добавление туда помощников избавит вас от необходимости добавлять их для каждого контроллера. Кроме того - я согласен с тем, что если то, что вы добавляете, следует рассматривать как фильтры ИЛИ Angular, они должны быть включены в код таким образом.
Кроме того, начиная с текущей версии 1.4.2, Angular предоставляет API «Провайдер», который разрешено вставлять в блоки конфигурации. Смотрите эти ресурсы для получения дополнительной информации:
https://docs.angularjs.org/guide/module#module-loading-dependencies
Внедрение зависимости AngularJS в значение внутри module.config
Я не думаю, что я собираюсь обновлять фактические блоки кода ниже, потому что я не очень активно использую Angular в эти дни, и я действительно не хочу рисковать новым ответом, не чувствуя себя комфортно, что это фактически соответствует новым лучшим практики. Если кто-то еще чувствует это, во что бы то ни стало, пойти на это.
РЕДАКТИРОВАТЬ 2/3/14:
Подумав об этом и прочитав некоторые другие ответы, я действительно предпочитаю вариант метода, предложенного @Brent Washburne и @Amogh Talpallikar. Особенно, если вы ищете утилиты, такие как isNotString () или аналогичные. Одно из явных преимуществ заключается в том, что вы можете повторно использовать их вне своего углового кода и использовать их внутри своей функции конфигурации (чего нельзя сделать со службами).
При этом, если вы ищете общий способ повторно использовать то, что должно быть должным образом сервисами, я думаю, что старый ответ все еще хорош.
Что бы я сделал сейчас:
app.js:
controller.js:
Тогда в своей части вы можете использовать:
Старый ответ ниже:
Возможно, было бы лучше включить их в качестве службы. Если вы собираетесь повторно использовать их на нескольких контроллерах, включая их в качестве службы, вам не придется повторять код.
Если вы хотите использовать сервисные функции в html-части, то вы должны добавить их в область действия этого контроллера:
$scope.doSomething = ServiceName.functionName;
Тогда в своей части вы можете использовать:
Вот способ, которым вы могли бы сохранить все это организованным и без лишних хлопот:
Разделите ваш контроллер, сервис и код маршрутизации / config на три файла: controllers.js, services.js и app.js. Модуль верхнего уровня - это «приложение», в котором зависимости app.controllers и app.services являются зависимостями. Затем app.controllers и app.services могут быть объявлены как модули в своих собственных файлах. Эта организационная структура только что взята из Angular Seed :
app.js:
services.js:
controller.js:
Тогда в своей части вы можете использовать:
Таким образом, вы добавляете только одну строку кода к каждому контроллеру и можете получить доступ к любой из функций служб, где бы ни была доступна эта область.
источник
Возвращаясь к этой старой теме, я хотел бы подчеркнуть, что
1 °) служебные функции могут (должны?) Быть добавлены в корневую область через module.run. Для этого нет необходимости создавать конкретный контроллер корневого уровня.
2 °) Если вы организуете свой код в отдельные модули, вы должны использовать угловые сервисы или фабрику, а затем внедрить их в функцию, переданную в блок выполнения, следующим образом:
3 °) Насколько я понимаю, в представлениях в большинстве случаев вам нужны эти вспомогательные функции для применения какого-либо форматирования к отображаемым строкам. В этом последнем случае вам нужно использовать угловые фильтры
И если вы структурировали некоторые вспомогательные методы низкого уровня в угловые сервисы или фабрики, просто внедрите их в свой конструктор фильтра:
И по вашему мнению:
источник
run
времени. Как насчет времени конфигурации? Разве нам не нужны коммунальные услуги там?Правильно ли я понимаю, что вы просто хотите определить некоторые служебные методы и сделать их доступными в шаблонах?
Вам не нужно добавлять их в каждый контроллер. Просто определите один контроллер для всех служебных методов и подключите этот контроллер к <html> или <body> (используя директиву ngController). Любые другие контроллеры, которые вы присоединяете в любом месте под <html> (имеется в виду где угодно, точка) или <body> (где угодно, кроме <head>), будут наследовать этот $ scope и иметь доступ к этим методам.
источник
<div class="main-container" ng-controller="UtilController as util">
тогда в любых внутренних видах:<button ng-click="util.isNotString(abc)">
Самый простой способ добавить служебные функции - оставить их на глобальном уровне:
Затем самый простой способ добавить служебную функцию (к контроллеру) - назначить ее
$scope
следующим образом:Тогда вы можете назвать это так:
или вот так:
РЕДАКТИРОВАТЬ:
Первоначальный вопрос заключается в том, является ли лучший способ добавить служебную функцию через службу. Я говорю нет, если функция достаточно проста (как в
isNotString()
примере, представленном ОП).Преимущество написания службы состоит в том, чтобы заменить ее на другую (посредством внедрения) для целей тестирования. В крайности, нужно ли вам вводить каждую функцию в свой контроллер?
Документация говорит, чтобы просто определить поведение в контроллере (например
$scope.double
): http://docs.angularjs.org/guide/controllerисточник
Вот простой, компактный и легкий для понимания метод, который я использую.
Сначала добавьте сервис в свой js.
Затем в вашем контроллере внедрите ваш вспомогательный объект и используйте любую доступную функцию с чем-то вроде следующего:
источник
Вы также можете использовать постоянный сервис как таковой. Определение функции вне константного вызова позволяет также быть рекурсивным.
источник
Почему бы не использовать наследование контроллера, все методы / свойства, определенные в области действия HeaderCtrl, доступны в контроллере внутри ng-view. $ scope.servHelper доступен во всех ваших контроллерах.
источник