2013-04-21 18 views
2

Я пытаюсь создать единую директиву, которая будет переключаться на элемент открытым или закрытым при нажатии ссылки триггера. Однако при нажатии одного триггера он переключает все экземпляры, а не один.AngularJS - Как ограничить область действия ngClick в нескольких экземплярах

Моего код выглядит следующим образом: http://plnkr.co/edit/IA1hrbAoUEvvkwDjRAh6

Может кто-нибудь помочь объяснить, как сделать эту работу с атрибутами и без определения моих шаблонов в самих директивах?

+0

http://docs.angularjs.org/guide/directive просто прочитайте все это, особенно * Объект определения директивы -> область * – Yoshi

+0

Да, документация - первое, на что я смотрел, но это довольно запутанный материал. Примеры всегда лучше для меня, поэтому я обращаюсь к SO. – Jon

ответ

1

Это потому, что вы используете один единственный экземпляр PancelCtrl для трех панелей. Таким образом, директива никогда не знает, какую панель следует переключать, потому что она не указана нигде.

У вас есть два различных варианта:

Создать один экземпляр для каждого элемента li:

<!-- (you have to remove 'data-ng-controller="PanelCtrl"' from 'div.subfooter') --> 
<li data-ng-controller="PanelCtrl"> 
    <a ng-click="toggle()" href="#">Panel A</a></a> 
    <div data-panel-trigger data-visible="visibility" class="panel span2"> 
    <p>Panel Content</p> 
    </div> 
</li> 
<li data-ng-controller="PanelCtrl"> 
    <a ng-click="toggle()" href="#">Panel B</a> 
    <div data-panel-trigger data-visible="visibility" class="panel span2"> 
    <p>Panel Content</p> 
    </div> 
</li> 
<li data-ng-controller="PanelCtrl"> 
    <a ng-click="toggle()" href="#">Panel C</a> 
    <div data-panel-trigger data-visible="visibility" class="panel span2"> 
    <p>Panel Content</p> 
    </div> 
</li> 

Делая это, вы будете иметь три PanelCtrl экземпляров, и каждый из них будет включать или дочерний элемент, отвечает на него.

Другой вариант - проверить, какая панель находится рядом с нажатой ссылкой (с помощью jQuery это делается с чем-то вроде $(this).siblings("div")). Но я думаю, что первый будет более подходящим, так как вы инкапсулируете поведение кода для каждой панели, которую хотите добавить на сайт.

Удачи вам!

+0

Спасибо! Это именно то, что я искал, - как избежать использования чего-то вроде '$ (this) .siblings (" div ")' или слишком полагаться на определенную структуру DOM. – Jon

0

Это потому, что все они влияют на один и тот же объем. Добавить

scope:{ 
    ... 
    ... 
} 

Для определения и использования директивы укажите атрибуты привязки в область действия директивы по мере необходимости.

3

Вот рабочий звенеть, который делает то, что вы хотите:

http://plnkr.co/edit/HcoyFyCSnrfmLu3lI7a6

Преимущество здесь состоит в том, что директива полностью самодостаточно, каждый из которых имеет собственный объект сфера. Обратите внимание, что вам больше не нужен контроллер.

Смотрите также: http://www.egghead.io/video/fYgdU7u2--g

Ваше новое определение директивы:

app.directive('panelTrigger', function() { 
    return { 
     scope:{}, 
     link: function($scope, element, attrs) { 

     $scope.toggle = function() { 
      $scope.visibility = !$scope.visibility; 
     }; 

     // Default visibility is false 
     $scope.visibility = false; 

     $scope.$watch(attrs.visible, function(newValue, oldValue) { 

      if (newValue === oldValue) { 
       return; 
      } 

      var elm = angular.element(element.children()[1]); 
      if (newValue) { 
      elm.attr('style', 'display: block;'); 
      } else { 
      elm.attr('style', 'display: none;'); 
      } 
     }); 
     } 
    }; 
}) 

И небольшое изменение в ваш HTML:

 <div data-panel-trigger data-visible="visibility"> 
     <a ng-click="toggle()" href="#">Panel A</a> 
     <div class="panel span2"> 
      <p>Panel Content</p> 
     </div> 
     </div> 
+0

+1 за отличную информацию. – Jon

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