访问Angularjs指令中的Sibling元素

时间:2017-07-28 12:15:41

标签: angularjs

我希望在html内容中包含上一个和下一个兄弟姐妹时显示'hr'分隔符:

<ul>
    <li ng-if="condition1">One</li>
    <li ng-if="condition2">Two</li>
    <divider>
    <li ng-if="condition3">Three</li>
    <li ng-if="condition4">Four</li>
</ul>

divider指令定义如下:

restrict: 'EA'
transclude: true
priority: -1
scope: {}
template: '<hr ng-if="show">'
link:
    post:(scope, element, attrs) ->
      // check if divider element has previous and next siblings here; How to do it??
      scope.show = true

我不确定如何访问兄弟元素。我尝试过element.sibling(),element.next()。

当我在控制台中使用element.parent()。html()时,它显示:

<!-- ngIf: condition1 -->
<!-- ngIf: condition2 -->
<divider><hr ng-if="show"></divider>
<!-- ngIf: condition3 -->
<!-- ngIf: condition4 -->

在将优先级设置为“-1”之前,不评估上述ng-if条件。

你能帮忙吗?

3 个答案:

答案 0 :(得分:1)

您可以使用本机JavaScript函数来检查上一个和下一个兄弟节点是否存在:

var prevNode = element[0].previousElementSibling;
var nextNode = element[0].nextElementSibling;

scope.show = prevNode && nextNode;

或者,您可以通过修改上例中的最后一行来检查上一个和下一个节点是否为li个元素:

scope.show = prevNode && nextNode && prevNode.nodeName === 'LI' && nextNode.nodeName === 'LI';

这是一个working plunker来引用。

答案 1 :(得分:1)

我认为你应该考虑使用CSS,它更简单。

您可以轻松隐藏任何分隔符:

  1. 位于列表的开头
  2. 位于列表的最后
  3. 是另一个分隔符(防止重复分隔符)
  4. 示例:

    .divider:first-child,
    .divider:last-child,
    .divider + .divider { display: none; }
    <ul>
      <li class="divider">-----</li>
      <li>One</li>
      <li class="divider">-----</li>
      <li>Two</li>
      <li>Three</li>
      <li>Four</li>
      <li class="divider">-----</li>
      <li class="divider">-----</li>
      <li class="divider">-----</li>
      <li>Five</li>
      <li class="divider">-----</li>
    </ul>

    这将按预期呈现

答案 2 :(得分:0)

您可以使用$imeout查看下一个摘要周期中已解决的条件。

一旦你这样做,你就可以通过兄弟姐妹并在指令前后有可见元素时显示它:

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

app.controller('MainCtrl', function($scope) {
  $scope.condition1 = true;
  $scope.condition2 = false;
  $scope.condition3 = false;
  $scope.condition4 = true;
});

app.directive('divider', function($timeout) {
  return {
    restrict: 'EA',
    transclude: true,
    priority: -1,
    scope: {},
    template: '<hr ng-if="show">',
    link: function(scope, element, attrs) {
      $timeout(function() {

        var myIndex, siblings = element.parent().children(),
          numSiblings = siblings.length;

        //find sibling position of this directive
        for (var i = 0; i < numSiblings; i++) {
          if (siblings[i] === element[0]) {
            myIndex = i;
            break;
          }
        }

        /* If myIndex is not 0 then there is an element before it.
           If myIndex is less than (numSibling - 1) then this is an element after it. */
        scope.show = (myIndex > 0 && myIndex < numSiblings - 1) ? true : false;
      }, 0);
    }
  };
});
<!DOCTYPE html>
<html ng-app="demo">

<head>
  <meta charset="utf-8" />
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.min.js"></script>
</head>

<body ng-controller="MainCtrl">
  <em>Example #1 - 1 (or more) elements before, 1 (or more) elements after:</em>
  <ul>
    <li ng-if="condition1">One</li>
    <li ng-if="condition2">Two</li>
    <divider></divider>
    <li ng-if="condition3">Three</li>
    <li ng-if="condition4">Four</li>
  </ul>
  <em>Example #2 - 0 elements before, 1 (or more) elements after:</em>
  <ul>
    <li ng-if="condition2">Two</li>
    <divider></divider>
    <li ng-if="condition3">Three</li>
    <li ng-if="condition4">Four</li>
  </ul>
  <em>Example #3 - 1 (or more) element before, 0 elements after:</em>
  <ul>
    <li ng-if="condition1">One</li>
    <li ng-if="condition2">Two</li>
    <divider></divider>
    <li ng-if="condition3">Three</li>
  </ul>
</body>

</html>

Plunker:http://plnkr.co/edit/S55WMP4dGzb2IP7JAnVP?p=preview