Índice de acesso do pai ng-repeat a partir do filho ng-repeat

218

Eu quero usar o índice da lista pai (foos) como argumento para uma chamada de função na lista filho (foos.bars).

Encontrei um post em que alguém recomenda o uso de $ parent. $ Index, mas $indexnão é propriedade de $parent.

Como posso acessar o índice dos pais 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>
Coder1
fonte
2
Parece funcionar corretamente para mim. Eu escrevi um desentupidor para demonstrá-lo funcionando: plnkr.co/edit/BenCDh4NUGPPHKWGsGMr?p=preview Você pode fornecer mais detalhes?
Piran
Obrigado por isso. Isso me levou a descobrir que meu problema era um erro na minha marcação.
#
@ Coder1, considere excluir esta pergunta.
Mark Rajcok
7
@ MarkRajcok Eu considerei isso ontem à noite, mas achei que seria útil para outras pessoas que procurassem por isso, então deixei.
Coder1
2
Bem, se você quiser mantê-lo, adicione uma resposta e aceite-a (para que esta pergunta não permaneça na lista "sem resposta").
Mark Rajcok

Respostas:

279

Meu código de exemplo estava correto e o problema era outra coisa no meu código real. Ainda assim, eu sei que foi difícil encontrar exemplos disso, então estou respondendo caso alguém esteja procurando.

<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>
Coder1
fonte
13
Além disso, isso me jogou por um tempo. Se houver uma diretiva de comutação de dados no seu código, você precisará subir um nível de escopo adicional- ($ parent. $ Parent. $ Index). Não é bonito, eu sei.
28813 Hairgami_Master
Acordado. Eu precisava passar $ parent. $ Parent. $ Index para minha função de controlador para obter o valor correto, mas depois vincular meu ng-show a $ parent. $ Index. Parece ser um bug angular para mim
Andrew Gray
Posso fazer algo assim se eu tiver uma repetição coleção junto com ng-repeat Aparentemente ele está retornando indefinido fazer o mesmo?
Ali Sadiq
6
Só para adicionar - você precisa de um $ parent adicional, mesmo que tenha um ng-ifno código, como acabei de descobrir.
quer
@PlastyGrove Obrigado por apontar que ng-ifrequer uma $parentreferência adicional . Me salvou um pouco de dor de cabeça.
iiminov
219

De acordo com os documentos ng-repeat , http://docs.angularjs.org/api/ng.directive:ngRepeat , você pode armazenar o índice de chave ou matriz na variável de sua escolha.(indexVar, valueVar) in values

então você pode escrever

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

Um nível acima ainda é bastante limpo com o índice $ parent. $, Mas com vários pais, as coisas podem ficar confusas.

Nota: $indexcontinuará sendo definido em cada escopo, não será substituído por fIndex.

Samuli Ulmanen
fonte
Eu não entendo a nota. O ponto principal desta questão não é esse porque não é verdade?
adam-beck
16
Esta deve ser a resposta validado como é mais limpo do que a $parent.$indexum
tdebroc
1
@ adam-beck Acho que eles querem dizer que, ao usar esse (fIndex, f)método, $ index ainda será definido (não omitido) - para que o índice se torne acessível como ambos $indexe fIndex.
Samuel Jaeschke
1
Para o meu caso, usar $indexnão funciona, mas adicionar o fIndexfaz. Eu não tenho uma única pista do porquê $index não funciona (em outros lugares do meu código), mas depois de lutar por vários dias, parei de me importar quando encontrei essa resposta. Também é um pouco mais legível quando você tem vários ng-repeats IMO.
Krøllebølle
@ Krøllebølle A razão pela qual funciona da maneira que você vê é que cada ng-repeatiteração cria seu próprio escopo, que também define o seu próprio $index, substituindo o pai $index. Se você incluir um elemento {{$index}}logo acima ou abaixo do ng-repeatelemento mais interno , verá o valor do pai e colocá-lo dentro do ng-repeatelemento mais interno mostrará a criança. O uso da abordagem nesta resposta apenas atribui o índice pai a uma variável cujo nome você escolheu ( fIndex), para que não seja sobrescrito por um escopo filho.
tavnab
44

Dê uma olhada na minha resposta para uma pergunta semelhante .
Ao usar o alias $index, não precisamos escrever coisas malucas como $parent.$parent.$index.


Solução mais elegante do que $parent.$indexusar o 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
fonte
3
também é mais seguro! se você adicionar um ng-se dentro do loop, você começa a $ index confuso, cheque: plnkr.co/52oIhLfeXXI9ZAynTuAJ
gonzalon
Eu tive que fazer sectionIndex = $ parent. $ Index #
Beanwah 11/11
A variável não é atualizada se você excluir um elemento que estava na matriz de repetição. . $ index e $ $ index pai é sempre a escolha segura
Bharat Bhandarkar
12

Você também pode obter o controle do índice dos principais pais pelo seguinte código

$parent.$parent.$index
AkRoy
fonte
1
Isso funciona bem para o meu projeto. Obrigado por fornecer uma solução incrível!
Canet Robern #
Isso não é extensível, aparentemente.
Ganesh Vellanki
Infelizmente, este é um exemplo de inveja de recursos e, obviamente, muitos casos problemáticos.
ChiefTwoPencils
2

Você pode simplesmente usar o uso de $ parent. $ Index .where parent representará o objeto pai que repete o objeto.

Vivek Panday
fonte
0

$ parent não funciona se houver vários pais. em vez disso, podemos definir uma variável de índice pai no init e usá-la

<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
fonte
veja a resposta da vucalur aqui também menciona isso. Em geral, esta é a maneira correta de seguir o IMO e geralmente apenas o uso adequado para o ng-init. Sempre que as pessoas chegam a $ parent, você está com problemas quando o contexto do seu código muda.
shaunhusain