2

I'm attempting to create a single directive that will toggle an element open or closed when a trigger link is clicked. However, when one trigger is clicked, it toggles all the instances open rather than a single one.

My code looks like this: http://plnkr.co/edit/IA1hrbAoUEvvkwDjRAh6

Can anyone help to explain how to make this work with attributes and without defining my templates in the directives themselves?

4

3 回答 3

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>
于 2013-04-21T23:25:33.197 回答
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"))。但我认为第一个会更合适,因为您将封装要在网站上添加的每个面板的代码行为。

祝你好运!

于 2013-04-21T23:25:43.543 回答
0

这是因为它们都影响相同的范围。添加

scope:{
  ...
  ...
 }

到您的指令定义并根据需要使用绑定属性到您的指令范围。

于 2013-04-21T23:14:54.477 回答