从子 ng-repeat 访问父 ng-repeat 的索引

Posted

技术标签:

【中文标题】从子 ng-repeat 访问父 ng-repeat 的索引【英文标题】:Access index of the parent ng-repeat from child ng-repeat 【发布时间】:2013-01-26 06:23:44 【问题描述】:

我想使用父列表 (foos) 的索引作为子列表 (foos.bars) 中函数调用的参数。

我发现有人推荐使用 $parent.$index 的帖子,但 $index 不是 $parent 的属性。

如何访问父 ng-repeat 的索引?

<div ng-repeat="f in foos">
  <div>
    <div ng-repeat="b in foos.bars">
      <a ng-click="addSomething($parent.$index)">Add Something</a>
    </div>
  </div>
</div>

【问题讨论】:

它对我来说似乎工作正常。我写了一个 plunker 来展示它的工作原理:plnkr.co/edit/BenCDh4NUGPPHKWGsGMr?p=preview你能提供更多细节吗? 谢谢你。这让我发现我的问题是我的标记中的一个错误。 @Coder1,请考虑删除此问题。 @MarkRajcok 我昨晚确实考虑过,但认为这对其他寻找如何做的人有帮助,所以我离开了。 好吧,如果你想保留它,请添加一个答案并接受它(这样这个问题就不会保留在“未回答”列表中)。 【参考方案1】:

我的示例代码是正确的,问题出在我的实际代码中。不过,我知道很难找到这样的例子,所以我会回答它以防其他人正在寻找。

<div ng-repeat="f in foos">
  <div>
    <div ng-repeat="b in foos.bars">
      <a ng-click="addSomething($parent.$index)">Add Something</a>
    </div>
  </div>
</div>

【讨论】:

另外,这让我有一段时间。如果您的代码中有一个 data-ng-switch 指令,您需要提升一个额外的范围级别 - ($parent.$parent.$index)。不漂亮,我知道。 同意。我需要将 $parent.$parent.$index 传递给我的控制器函数以获取正确的值,然后将我的 ng-show 绑定到 $parent.$index。对我来说似乎是一个有角的错误 如果我有一个 Collection 重复和 ng-repeat,我可以做这样的事情吗?显然它返回 undefined 做同样的事情 只是添加 - 你需要一个额外的 $parent 即使你有一个 ng-if 在我刚刚发现的代码中。 @PlastyGrove 感谢您指出ng-if 需要和额外的$parent 参考。让我头疼不已。【参考方案2】:

根据 ng-repeat docs http://docs.angularjs.org/api/ng.directive:ngRepeat,您可以将键或数组索引存储在您选择的变量中。 (indexVar, valueVar) in values

这样你就可以写了

<div ng-repeat="(fIndex, f) in foos">
  <div>
    <div ng-repeat="b in foos.bars">
      <a ng-click="addSomething(fIndex)">Add Something</a>
    </div>
  </div>
</div>

$parent.$index 上一级仍然很干净,但如果有几个父级,事情可能会变得一团糟。

注意:$index 将继续在每个范围内定义,不会被fIndex 替换。

【讨论】:

我看不懂注释。这个问题的重点不是因为那不是真的吗? 这应该是经过验证的答案,因为它比$parent.$index one 更干净 @adam-beck 我认为他们的意思是当使用这个(fIndex, f) 方法时,$index 仍然会被定义(而不是省略) - 所以索引可以作为$indexfIndex 访问. 就我而言,使用$index 不起作用,但添加fIndex 可以。我对 why $index 不起作用(它在我的代码中的其他地方也起作用)一无所知,但是经过几天的努力,当我找到这个答案时,我不再关心了。当您有多个 ng-repeats IMO 时,它也更具可读性。 @Krøllebølle 它以您看到的方式工作的原因是每个 ng-repeat 迭代创建自己的范围,该范围还定义了自己的 $index,覆盖了父级的 $index。如果您在最里面的ng-repeat-ed 元素的上方或下方包含$index,您将看到父级的值,并将其放在最里面的ng-repeat-ed 元素中将显示子级的值。使用此答案中的方法只是将父索引分配给您选择的名称(fIndex)的变量,因此它不会被子范围覆盖。【参考方案3】:

看看my answer to a similar question。 通过给$index 起别名,我们不必写像$parent.$parent.$index 这样疯狂的东西。


$parent.$index 使用ng-init 时更优雅的解决方案:

<ul ng-repeat="section in sections" ng-init="sectionIndex = $index">
    <li  class="section_title section.active" >
        section.name
    </li>
    <ul>
        <li class="tutorial_title tutorial.active" ng-click="loadFromMenu(sectionIndex)" ng-repeat="tutorial in section.tutorials">
            tutorial.name
        </li>
    </ul>
</ul>

Plunker:http://plnkr.co/edit/knwGEnOsAWLhLieKVItS?p=info

【讨论】:

也更安全!如果你在循环中添加一个 ng-if,你会得到 $index 的混乱,检查:plnkr.co/52oIhLfeXXI9ZAynTuAJ 我不得不做 sectionIndex = $parent.$index 如果删除重复数组中的元素,变量不会更新。 $index 和 $parent.$index 始终是安全的选择【参考方案4】:

您可以简单地使用 $parent.$index 。其中 parent 将表示父重复对象的对象。

【讨论】:

【参考方案5】:

您还可以通过以下代码控制祖父索引

$parent.$parent.$index

【讨论】:

这对我的项目很有效。感谢您提供出色的解决方案! 这显然是不可扩展的。 不幸的是,这在某种程度上是功能嫉妒的一个例子,在许多情况下显然存在问题。【参考方案6】:

如果有多个父母,$parent 不起作用。取而代之的是,我们可以在 init 中定义一个父索引变量并使用它

<div data-ng-init="parentIndex = $index" ng-repeat="f in foos">
  <div>
    <div data-ng-init="childIndex = $index" ng-repeat="b in foos.bars">
      <a ng-click="addSomething(parentIndex)">Add Something</a>
    </div>
  </div>
</div>

【讨论】:

查看 vucalur 的回答,这里也提到了这一点。一般来说,这是进入 IMO 的正确方法,通常只正确使用 ng-init。任何时候,当你的代码上下文发生变化时,当人们到达 $parent 时,你就是在自找麻烦。

以上是关于从子 ng-repeat 访问父 ng-repeat 的索引的主要内容,如果未能解决你的问题,请参考以下文章

AngularJS 从子控制器访问父范围

Meteor - 从子助手访问父模板变量

从子片段访问父片段方法

当父组件使用 ng-content Angular 时从子组件访问父组件

从子组件访问父组件。使用服务? @ContentChildren 呢?

是否可以从子网格视图访问父列表视图项目?