2015-03-21 2 views
1

На основании этого примера throbberDirective, Как добавить пользовательскую директиву к контроллеру, чтобы вы могли вызвать функции show() hide()? Я не могу избавиться от следующей ошибки:Как загрузить директиву в контроллер?

Error: [$injector:unpr] Unknown provider: inputThrobberProvider <- inputThrobber <- landingCtrl 

Пример кода:

var app = angular.module('myapp', ['ngAnimate', 'ui.router', 'templates']); 

app.directive('inputThrobber', [function() { 
    return { 
     restrict: 'A', 
     require: 'ngModel', 
     controller: function($scope, $element) { 
     var inputThrobberCtrl = { 
      show: function() { 
      $element.addClass('throbbing'); 
      }, 
      hide: function() { 
      $element.removeClass('throbbing'); 
      } 
     }; 

     return inputThrobberCtrl; 
     } 
    }; 
    }]) 
    .controller('landingCtrl', ['$scope', 'geolocation', 'inputThrobber', function($scope, geolocation, inputThrobber) { 

    // inputThrobber.show() 
    geolocation.getAddress().then(function(address) { 
     $scope.address = address; 
     }).catch(function(err) { 
     $scope.error = error; 
     $scope.address = ''; 
     }) 
     .finally(function() { 
     // $inputThrobber.hide() 
     }); 

    }]); 
+0

Что вы хотите сделать это, когда оно есть? –

+2

Попытка ввести директиву в контроллер не имеет смысла. Директивы предназначены для выполнения манипуляций с DOM. Контроллеры не должны знать о DOM. –

+0

Я пытаюсь добавить директиву [inputThrobber] (http://codepen.io/apuchkov/pen/lwkdq) непосредственно в контроллере, поэтому, когда мои ресурсы разрешаются, я покажу загрузку счетчика. – luzny

ответ

3

Вот пример использования, который отправляет событие, чтобы показать/скрыть кок:

app.directive('inputThrobber', [function() { 
    return { 
     restrict: 'A', 
     require: 'ngModel', 
     controller: function($scope, $element) { 
     $scope.$on('startThrobbing', function() { 
      $element.addClass('throbbing'); 
     }); 
     $scope.$on('stopThrobbing', function() { 
      $element.removeClass('throbbing'); 
     }); 
     } 
    }; 
    }]) 

.controller('landingCtrl', ['$scope', 'geolocation', function($scope, geolocation) { 
    $scope.$broadcast('startThrobbing'); 
    geolocation.getAddress().then(function(address) { 
     $scope.address = address; 
     }).catch(function(err) { 
     $scope.error = error; 
     $scope.address = ''; 
     }) 
     .finally(function() { 
     $scope.$broadcast('stopThrobbing'); 
     }); 
}]); 
+1

не работает, если первая трансляция не запускается с задержкой: '$ timeout (function() {$ scope. $ Broadcast ('startThrobbing');});', я не мог найти лучшего решения, возможно, у вас есть предложения? – luzny

+1

@luzny Похоже, что контроллер создается и транслирует событие до того, как директива запущена и работает. Тайм-аут - это одно решение. Если вы чувствуете, что это взлома, вы можете рассмотреть одно из других способов связи между контроллером и директивой: использование областей. Директива должна быть в той же области действия или в детском пространстве контроллера. Затем установите логическую переменную ('$ scope.loading = true;'), чтобы вызвать директиву. У каждого средства коммуникации есть свои плюсы и минусы. –

+1

Окончательное решение будет использовать [$ httpInterceptor] (https://docs.angularjs.org/api/ng/service/$http#interceptors), чтобы обнаружить, когда запрос сервера завершен. Затем вы можете показать индикатор загрузки на глобальной основе, а не только этот вид. Я видел кучу проектов в Github, которые уже делают такие вещи. –

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