Связь между директивами братьев и сестер внутри изолированной области

0

Я пытаюсь дать одному ребенку указание сообщить своему родному брату, что информация обновлена.

У меня есть эта разметка:

  <rp-nav>
     <rp-nav-item cat="1"></rp-nav-item>
     <rp-nav-item cat="2"></rp-nav-item>
     <rp-nav-item cat="3"></rp-nav-item>

     <rp-flyout></rp-flyout>
  </rp-nav>

  <hr>

  <rp-nav>
    <rp-nav-item cat="one"></rp-nav-item>
    <rp-nav-item cat="two"></rp-nav-item>
    <rp-nav-item cat="three"></rp-nav-item>

    <rp-flyout></rp-flyout>
  </rp-nav>

Я использую события таким образом:

angular.module('rpNavItem', [])
  .directive('rpNavItem', function() {
    return {
        restrict: 'E',
        controller: function($scope) {},
        controllerAs: 'ctrl',
        bindToController: true,
        // scope: true,
        template: function(el, attrs) {
          return  '<div>Item ' + attrs.cat + '</div>';
        },
        link: function(scope, el, attrs, ctrl) {
            el.on('click', function(){
                scope.$broadcast('selectedCat', attrs.cat);
            });
        }
    };
});

angular.module('rpFlyout', []).directive('rpFlyout', function() {
  return {
    restrict: 'E',
    controllerAs: 'ctrl',
    bindToController: true,
    // scope:true,
    controller: function($scope) {},
    template: '<p style="background-color: lightblue">{{category}}</p>',
    link: function(scope) {
      scope.$on('selectedCat', function(event, value){
        scope.category = value;
        scope.$digest();
        console.log(value);
      });
    }
  };
});

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

Plunker

Теги:

1 ответ

1
Лучший ответ

Каждая область изолята является дочерней из одного и того же $rootScope поэтому вы не можете использовать события для разделения директив. $broadcast -ed используются для глобальной (до корневой) связи.

Чтобы напрямую связываться с директивами, вы можете использовать свойство require для директив, поэтому rpNavItem может потребовать rpNav и использовать rpNav для совместного использования.

Для этого примера не требуется rpFlyout, javascript:

angular.module('app', ['rpNav']);

angular.module('rpNav', [])
    .directive('rpNav', function() {
        return {
            scope: true,
            controller: ['$scope', function ($scope) {
              this.setSelectedCat = function (cat) {
                $scope.category = cat;
              }
            }]
        };
    });

angular.module('rpNav')
    .directive('rpNavItem', function() {
        return {
            restrict: 'E',
            scope: {
              cat: '@'
            },
            template: function (el, attrs) {
              return  '<div>Item ' + attrs.cat + '</div>';
            },
            require: '^rpNav',
            link: function (scope, el, attrs, rpNav) {
                el.on('click', function(){
                    scope.$apply(function () {
                      rpNav.setSelectedCat(scope.cat);
                    });
                });
            }
        };
    });

HTML может стать чем-то вроде:

<div rp-nav>
  <rp-nav-item cat="1"></rp-nav-item>
  <rp-nav-item cat="2"></rp-nav-item>
  <rp-nav-item cat="3"></rp-nav-item>

  <p style="background-color: lightblue">{{category}}</p>
</div>

<hr>

<div rp-nav>
  <rp-nav-item cat="one"></rp-nav-item>
  <rp-nav-item cat="two"></rp-nav-item>
  <rp-nav-item cat="three"></rp-nav-item>

  <p style="background-color: lightblue">{{category}}</p>
</div>

Если вы хотите сохранить директиву rpFlyout по какой-либо причине, вы можете сделать это и изолированным хранилищем и передать текущую категорию в атрибут (непроверенный код):

<rp-flyout category="category"></rp-flyout>

Директива:

[...]
.directive('rpFlyout', function() {
        return {
            scope: {
              'category': '='
            },
            template: '<p style="background-color: lightblue">{{category}}</p>'
        };
    });

Ещё вопросы

Сообщество Overcoder
Наверх
Меню