查找 transcluded 指令的子元素,但排除其自己的嵌套指令子元素

Posted

技术标签:

【中文标题】查找 transcluded 指令的子元素,但排除其自己的嵌套指令子元素【英文标题】:Find child elements of transcluded directive but exclude its own nested directive child elements 【发布时间】:2017-04-13 13:07:16 【问题描述】:

假设我有以下代码:(Plunkr: https://plnkr.co/edit/lhSmKWq3dkDScLQlXMAX)

<directive-a id="1">
  <a href="">1</a>
  <a href="">1</a>

  <directive-b>
    <a href="">1</a>
  </directive-b>

  <directive-a id="2">
      <a href="">2</a>

      <directive-a id="3">
        <a href="">3</a>
      </directive-a>

    </directive-a>

</directive-a>

directiveAdirectiveB 是 2 个不同的嵌入指令。我们专注于directiveAdirectiveB 只是表示可以有另一个指令而不是directiveA

如何每个directiveA 只查找和修改自己的标签元素?也就是说,在这种情况下,directiveA#1怎么只能查找和修改3个a标签,directiveA#2directiveA#3各自只能查找和修改自己的1个a标签?

请参阅 plunkr 了解我的尝试,但到目前为止还没有运气。

【问题讨论】:

【参考方案1】:

请检查这是否对您有帮助。

var app = angular.module('plunker', []);

app.controller('MainCtrl', function() 
  var vm = this;
);

app.directive('directiveA', function($timeout) 
  return 
    link: function(scope, element) 
      // class name to be used as a filter
      var className = 'aClass';
      // array where suitable element ids will be collected into
      var collectedIds = [];
      // demarking boundaries - all directiveA's will have this class added to them 
      element.addClass(className);
      // initiating the collection process
      traverse(element);
      // printing the result
      console.log('scope a', scope.id, collectedIds);

      /**
       * responsible for traversing the DOM tree starting from the current
       * element collecting IDs of elements of interest.
       *
       * elements of interest in this case are:
       * "all descendants of the current node which do not have the class 'aClass'"
       */
      function traverse(element) 
        angular.forEach(element.children(), function(c) 
          // wrapping dom element
          var child = angular.element(c);
          // is the current child of a desirable/valid type
          if (isValidElement(child)) 
            var childId = child.attr('id');
            if (childId) 
              // collecting the current element's id 
              collectedIds.push(childId);
            
            // recurssing on the current element child elements
            traverse(child);
          
        );
      

      /**
       * responsible for deciding if the current element
       * is of a desirable type to be traversed.
       */
      function isValidElement(element) 
        return !element.hasClass(className);
      

    ,
    restrict: 'E',
    scope: 
      id: "="
    ,
    transclude: true,
    replace: true,
    template: '<div ng-transclude></div>'
  
);

app.directive('directiveB', function() 
  return 
    restrict: 'E',
    scope: ,
    transclude: true,
    replace: true,
    template: '<div ng-transclude></div>'
  
);
* 
  list-style-type: none;
<!DOCTYPE html>
<html ng-app="plunker">

<link rel="stylesheet" href="style.css" />
<script data-require="angular.js@1.5.x" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>
<script src="app.js"></script>


<body ng-controller="MainCtrl as vm">
  <directive-a id="1">
    <a id="1" href="">1</a>
    <a id="2" href="">1</a>

    <directive-b>
      <a id="3" href="">1</a>

      <div>
        <a id="6" href="">1</a>
      </div>
    </directive-b>

    <directive-a id="2">
      <a id="4" href="">2</a>

      <directive-a id="3">
        <a id="5" href="">3</a>
      </directive-a>

    </directive-a>

  </directive-a>

  <h3>Result example in console:</h3>
  <ul>
    <li>scope a 3: [5]</li>
    <li>scope a 2: [4]</li>
    <li>scope a 1: [1,2,3,6]</li>
  </ul>
</body>

</html>

【讨论】:

以上是关于查找 transcluded 指令的子元素,但排除其自己的嵌套指令子元素的主要内容,如果未能解决你的问题,请参考以下文章

什么是 ng-transclude?

如何从 Angular 2 的指令中附加动态 DOM 元素?

查找具有相同类但排除单击的元素的所有元素? [复制]

AngularJS Transcluded指令的范围来自其他指令

translclude

directive(指令里的)的compile,pre-link,post-link,link,transclude