AngularJS:在ng-repeat中爬上作用域树



我想建立一个飞出树菜单,将active类添加到悬停元素,并在任何兄弟姐妹悬停时删除它。

这样,当用户鼠标离开菜单时,菜单将保持打开状态。

弹出式菜单是递归的,因为它可以是任意数量的深度。

为了从兄弟姐妹中移除一个类,我必须知道它们的父或兄弟状态。我更愿意用数据结构来做这件事,但如果需要,将使用DOM遍历。

I have try:

  • 使用范围。$parent在悬停处理程序中(但处理程序知道的范围是指令范围,而不是ng-repeat范围)
  • 将事件传递给悬停处理程序并调用$(evt).siblings()(但angular大叫,说我无法从表达式访问DOM)
  • 在本地ng-repeat作用域中设置.parent属性(但是事件处理程序无法访问模板继承的这些值)
  • 使用递归指令,所以树中的每个叶子都是另一个指令。这会使浏览器崩溃。(我认为是因为它试图在寻找循环上的退出条件之前编译指令)
  • 为树中的每个叶子添加一个控制器。这使得作用域树很大,并且没有提供一种访问兄弟节点的干净方式。但它是功能性的。请看下面我的回答。

我不知道如何在Angular中做到这一点。在jQuery中做到这一点很简单:$(e.target).siblings().removeClass('active')。我该怎么做呢?

我做了一个Plunker来演示在递归ng-repeat中访问兄弟姐妹的问题:http://plnkr.co/edit/vBYYt6sTvWKN9TXz9SC5?p=preview

一个很好的解决方案是使用一个变量来跟踪树的每一层的活动叶子。在这个方法中,在父作用域中声明变量,而在叶作用域中赋值。在任何给定的时间只有一个兄弟是活动的:ng-class="{active: branch.name == activeLeaf}"

Plunkr由Cam[tab]写自#angularjs: http://plnkr.co/edit/u5EiP2DmQtBROxL7Qq53?p=preview

可以在每个ng-repeat上面使用一个控制器来声明作用域,但这会增加很多作用域层。您可以使用嵌套指令来包含范围,但这些指令会无限递归。Cam的解决方案,如上所述,包括ng-include中的嵌套指令,它生成了一个很好的精简作用域树,并避免了无限递归。

您可以在使用ng-repeat时使用$index为所有兄弟节点提供id,并在执行ng-repeat的div上添加以下代码

ie。

id="$index"
使用

ng-class={active: selected==$index}

点击改变所选

的值
ng-click="selected=$index"

可以使用$parent访问父循环的索引。$index从你的内部ng-repeat循环

下面是不是一个好的答案,但它是功能性的。我想提供它,让人们看到我能找到的唯一功能解决方案有多糟糕:)

如果你在递归树的每个叶子上添加一个控制器,并将悬停或点击处理程序附加到该控制器上,你就可以访问处理程序中该级别的作用域。因为作用域提供了一个$parent方法,所以您可以往上爬并获得兄弟节点。

这听起来并不是很不干净,但是等着看你要爬出多少但丁式的关卡吧。

Leaf.html:

<a href
 ng-click="onClick($event, branch)"
 ng-controller="LeafController"
 >
{{ branch.name }}
<span ng-if="branch.children">&gt;</span>
<ul ng-if="branch.children">
  <li ng-repeat="branch in branch.children">
    <ng-include src="'leaf.html'"></ng-include>
  </li>
</ul>

LeafController:

angular.module('app').controller('LeafController', function($scope) 
  $scope.onClick = function(evt, leaf) {
    evt.stopPropagation();
    console.log('$scope', $scope); // Should be able to get to siblings now, right?
  };
});

兄弟对象现在可以在这个位置访问(我希望我是在开玩笑):

$scope.$parent.$parent.$parent.$parent.$parent.$parent.branch.children

我不想依赖这个链条。一定有更好的办法,对吧?

最新更新