Чи можу я ввести послугу в директиву в AngularJS?


234

Я намагаюся ввести послугу в директиву, як нижче:

 var app = angular.module('app',[]);
 app.factory('myData', function(){
     return {
        name : "myName"
     }
 });
 app.directive('changeIt',function($compile, myData){
    return {
            restrict: 'C',
            link: function (scope, element, attrs) {
                scope.name = myData.name;
            }
        }
 });

Але це повертає мені помилку Unknown provider: myDataProvider. Може хтось, будь ласка, загляне в код і скаже, чи я роблю щось не так?

Відповіді:


388

Ви можете робити ін'єкції за директивами, і це виглядає так, як це робиться скрізь.

app.directive('changeIt', ['myData', function(myData){
    return {
        restrict: 'C',
        link: function (scope, element, attrs) {
            scope.name = myData.name;
        }
    }
 }]);

13
Я думаю, що це краще рішення, оскільки воно працює навіть після мінімізації коду.
czerasz

5
Я повинен був додати '_myData = myData' до повернення {}, а потім посилатись на об'єкт як _myData всередині функції посилання.
Джеллінг

Дякую @Jelling. Я повинен був зробити те саме. Цікаво, чи хтось там міг сказати нам, чому ...?
sfletche

6
якась конкретна причина вводити $ compile в директиву? це, здається, ніде не використовується.
гру

4
Чи є рішення для ін'єкції, якщо ви хочете створити функцію зв'язку поза викликом директиви?
ThinkBonobo

19

Змініть визначення директиви з app.moduleна app.directive. Крім того, все виглядає добре. До речі, дуже рідко вам доводиться вводити послугу в директиву. Якщо ви вводите послугу (яка зазвичай є джерелом даних або моделлю) у вашу директиву (яка є частиною перегляду), ви створюєте прямий зв'язок між вашим представленням та моделлю. Їх потрібно відокремити, з'єднавши їх за допомогою контролера.

Це добре працює. Я не впевнений, що ти робиш, що не так. Ось ця робота працює.

http://plnkr.co/edit/M8omDEjvPvBtrBHM84Am


Чи можете ви надати приклад, будь ласка
Виняток

@Exception Чи можете ви поставити свій код у скрипці? Я можу подивитися і зрозуміти, чому ваш код не працює і, ймовірно, допоможе вам виправити його.
ganaraj

@Exception додав робочий планк, який показує, що код працює.
ganaraj

3
Щойно я виявив щось: якщо ви визначите ін'єкцію в параметрах функції, function($location) { ...але насправді не посилаєтесь на $locationфункцію всередині функції, AngularJS не виконає ін'єкцію. Єдиний раз, коли ви коли-небудь помітили таку поведінку, це всередині налагоджувача.
Вальтер Стабош

13
Я не впевнений, що згоден з вашим "сполученим" коментарем. Ми вже з'єднуємо контролер і сервіс у всьому світі - ми не можемо програмно замінити реалізацію служби під час виконання. Що означає, що один контролер отримує єдину послугу. Однак директиви мають ізольовану конфігурацію на тег сторінки, тому, можливо, ми надаємо різні послуги різним екземплярам директив. Мені здається, це менш відокремлено.
хлопець mograbi

11

Ви також можете скористатися послугою $ inject, щоб отримати будь-яку послугу, яка вам подобається. Я вважаю це корисним, якщо я не знаю назви служби достроково, але знаю інтерфейс сервісу. Наприклад, директива, яка підключить таблицю до кінцевої точки ngResource або загальної кнопки видалення-запису, яка взаємодіє з будь-якою кінцевою точкою api. Ви не хочете повторно реалізувати директиву таблиць для кожного контролера чи джерела даних.

template.html

<div my-directive api-service='ServiceName'></div>

my-directive.directive.coffee

angular.module 'my.module'
  .factory 'myDirective', ($injector) ->
    directive = 
      restrict: 'A'
      link: (scope, element, attributes) ->
        scope.apiService = $injector.get(attributes.apiService)

тепер ваша "анонімна" послуга повністю доступна. Якщо це, наприклад, ngResource, ви можете використовувати стандартний інтерфейс ngResource для отримання своїх даних

Наприклад:

scope.apiService.query((response) ->
  scope.data = response
, (errorResponse) ->
  console.log "ERROR fetching data for service: #{attributes.apiService}"
  console.log errorResponse.data
)

Я вважав, що ця методика дуже корисна при створенні елементів, особливо взаємодіючих з кінцевими точками API.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.