Índice de acceso del ng-repeat padre del ng-repeat hijo

218

Quiero usar el índice de la lista principal (foos) como argumento para una llamada de función en la lista secundaria (foos.bars).

Encontré una publicación en la que alguien recomienda usar $ parent. $ Index, pero $indexno es propiedad de $parent.

¿Cómo puedo acceder al índice del padre 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>
Codificador1
fuente
2
Parece que funciona correctamente para mí. He escrito un plunker para mostrar que funciona: plnkr.co/edit/BenCDh4NUGPPHKWGsGMr?p=preview ¿Puede proporcionar más detalles?
Piran
Gracias por eso. Me llevó a encontrar que mi problema era un error en mi marcado.
Codificador1
@ Coder1, considere eliminar esta pregunta.
Mark Rajcok
77
@ MarkRajcok Lo consideré anoche, pero pensé que sería útil para otros que buscan cómo hacer esto, así que lo dejé.
Codificador1
2
Bueno, si desea conservarla, agregue una respuesta y acéptela (para que esta pregunta no permanezca en la lista "sin respuesta").
Mark Rajcok

Respuestas:

279

Mi código de ejemplo era correcto y el problema era algo más en mi código real. Aún así, sé que fue difícil encontrar ejemplos de esto, así que lo estoy respondiendo en caso de que alguien más esté mirando.

<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>
Codificador1
fuente
13
Además, esto me arrojó por un tiempo. Si hay una directiva de cambio de datos dentro de su código, deberá subir un nivel de alcance adicional ($ parent. $ Parent. $ Index). No es bonito, lo sé.
Hairgami_Master
Convenido. Necesitaba pasar $ parent. $ Parent. $ Index a mi función de controlador para obtener el valor correcto, pero luego vincular mi ng-show a $ parent. $ Index. Me parece un error angular
Andrew Gray
¿Puedo hacer algo como esto si tengo una repetición de Colección junto con ng-repeat? Aparentemente está regresando indefinido haciendo lo mismo
Ali Sadiq
66
Solo para agregar: necesita un $ parent adicional incluso si tiene uno ng-ifen el código como acabo de descubrir.
Plasty Grove
@PlastyGrove Gracias por señalar que ng-ifrequiere una $parentreferencia adicional . Me ahorró un poco de dolor de cabeza.
iiminov
219

De acuerdo con ng-repeat docs http://docs.angularjs.org/api/ng.directive:ngRepeat , puede almacenar la clave o el índice de matriz en la variable que elija.(indexVar, valueVar) in values

para que puedas escribir

<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>

Un nivel superior todavía está bastante limpio con $ parent. $ Index pero varios padres suben, las cosas pueden complicarse.

Nota: $indexcontinuará definiéndose en cada ámbito, no se reemplaza por fIndex.

Samuli Ulmanen
fuente
No entiendo la nota. ¿No es el objetivo de esta pregunta porque eso no es cierto?
Adam-Beck
16
Esta debe ser la respuesta validado, ya que es más limpio que el $parent.$indexuno
tdebroc
1
@ adam-beck Creo que significan que cuando se usa este (fIndex, f)método, $ index todavía se definirá (no se omitirá), por lo que el índice se vuelve accesible como ambos $indexy fIndex.
Samuel Jaeschke
1
Para mi caso, usar $indexno funciona, pero agregar el fIndexsí. No tengo ni idea de por qué $index no funciona (funciona en otros lugares de mi código), pero después de luchar durante varios días, dejé de preocuparme cuando encontré esta respuesta. También es un poco más legible cuando tienes múltiples ng-repeatIMO.
Krøllebølle
@ Krøllebølle la razón por la que funciona de la forma en que lo ve es que cada ng-repeatiteración crea su propio alcance, que también define el suyo $index, sobrescribiendo el del padre $index. Si incluye un {{$index}}derecho encima o debajo del ng-repeatelemento más interno , verá el valor del padre, y al colocarlo dentro del ng-repeatelemento más interno le mostrará el del niño. El uso del enfoque en esta respuesta solo asigna el índice principal a una variable cuyo nombre ha elegido ( fIndex) para que no se sobrescriba con un ámbito secundario.
tavnab
44

Echa un vistazo a mi respuesta a una pregunta similar .
Aliasing $indexno tenemos que escribir cosas locas como $parent.$parent.$index.


Solución mucho más elegante que $parent.$indexestá usando 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

vucalur
fuente
3
¡también es más seguro! si agrega un ng-if dentro del ciclo, obtiene el índice $ desordenado, verifique: plnkr.co/52oIhLfeXXI9ZAynTuAJ
gonzalon
Tuve que hacer sectionIndex = $ parent. $ Index
Beanwah
La variable no se actualiza si elimina un elemento que estaba en la matriz de repetición. $ index y $ parent. $ index es siempre la opción segura
Bharath Bhandarkar
12

También puede obtener el control del índice de padre principal mediante el siguiente código

$parent.$parent.$index
AkRoy
fuente
1
Esto funciona bien para mi proyecto. ¡Gracias por proporcionar una solución increíble!
Canet Robern
Esto no es extensible, aparentemente.
Ganesh Vellanki
Desafortunadamente, este es un ejemplo de envidia de características y obviamente problemático en muchos casos.
ChiefTwoPencils
2

Simplemente puede usar use $ parent. $ Index. Donde parent representará el objeto del objeto repetido padre.

Vivek Panday
fuente
0

$ parent no funciona si hay varios padres. en lugar de eso, podemos definir una variable de índice padre en init y usarla

<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>
Gajanan Prasad
fuente
vea la respuesta de vucalur aquí también menciona esto. En general, esta es la forma correcta de ir a la OMI y, en general, solo el uso adecuado para ng-init. Cada vez que las personas alcanzan hasta $ parent, está solicitando problemas cuando cambia el contexto de su código.
shaunhusain