Прослушивание широковещательного события от контроллера внутри директивы

#javascript #angularjs

#javascript #angularjs

Вопрос:

У меня есть контроллер, который транслирует событие, когда некоторый контент загружается следующим образом

 angular.module('myApp')
  // Using rootScope now
  .controller('SubCtrl', ['$rootScope', '$scope', '$http', function ($rootScope, $scope, $http) {
    $http.get('/scripts/data/content.json')
      .then(function(response) {
        $scope.content = response.data;
        $rootScope.$broadcast('dataloaded');
      });
}]);
  

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

 angular.module('myApp')
  .directive('matchHeight', ['$timeout', function ($timeout) {
    var linkFunction = function(scope, element, attrs) {
      scope.$on('dataloaded', function() {
        $timeout(function() {
          angular.element(element).matchHeight(attrs);
        });
      });
  };

  return {
    restrict: 'A',
    link: linkFunction
  };
}]);
  

Я использую ui-router для управления состояниями
Это HTML

 <div class="row usps">
  <div class="col-sm-4 usp-block" ng-repeat="block in content.marketing" match-height>
    // Inner HTML
  </div>
</div>
  

Широковещательное событие не распознается из директивы. Что я делаю не так?

Комментарии:

1. убедитесь, что оно content.marketing содержит данные и scope.$on выполняется раньше .$broadcast . Поместите журнал и проверьте порядок выполнения.

Ответ №1:

Из-за того факта, что вы находитесь внутри ngRepeat , содержимое будет отображаться только после запуска широковещательной рассылки, поэтому директива будет. Тогда ваша директивная ссылка будет подписываться только на событие, но оно не будет выполняться, потому что оно уже было выполнено до того, как это ngRepeat завершит рендеринг вашей директивы.

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

 angular.module('myApp')
  .directive('matchHeight', ['$timeout', function ($timeout) {
    var linkFunction = function(scope, element, attrs) {
      $timeout(function() {
        angular.element(element).matchHeight(attrs);
      });
  };

  return {
    restrict: 'A',
    link: linkFunction
  };
}]);
  

Комментарии:

1. Я пытался использовать $ rootScope. Но оно все еще не достигает области действия директивы. Я отредактирую свой вопрос, чтобы вы могли видеть, что я изменил

2. @Gert-JanKooijmans извините, еще не закончил, я провел несколько тестов и понял, что происходит. Обновил мой ответ