Como usar ng-repeat para dicionários em AngularJs?

285

Eu sei que podemos facilmente usar ng-repeat para objetos json ou matrizes como:

<div ng-repeat="user in users"></div>

mas como podemos usar o ng-repeat para dicionários, por exemplo:

var users = null;
users["182982"] = "{...json-object...}";
users["198784"] = "{...json-object...}";
users["119827"] = "{...json-object...}";

Eu quero usar isso com o dicionário de usuários:

<div ng-repeat="user in users"></div>

É possível?. Se sim, como posso fazer isso no AngularJs?

Exemplo para minha pergunta: No C #, definimos dicionários como:

Dictionary<key,value> dict = new Dictionary<key,value>();

//and then we can search for values, without knowing the keys
foreach(var val in dict.Values)
{
}

Existe uma função interna que retorna os valores de um dicionário como em c #?

Vural
fonte
1
Qual é a diferença entre um dicionário e um objeto JSON? Eu acredito que não há nenhum em javascript!
Markmarijnissen
8
@markmarijnissen: um objeto JSON possui regras de sintaxe mais rigorosas que um objeto JavaScript . E, como já estamos no Pedant's Corner, não existe um "Dicionário" em JavaScript. Nós apenas os chamamos de objetos.
Paul D. Waite

Respostas:

556

Você pode usar

<li ng-repeat="(name, age) in items">{{name}}: {{age}}</li>

Veja a documentação do ngRepeat . Exemplo: http://jsfiddle.net/WRtqV/1/

Artem Andreev
fonte
53
Não foi isso que pedi, mas exatamente o que eu queria. Obrigado Artem Andreev
Vural
1
Como podemos usar o filtro neste ng-repeat. Não está funcionando no meu caso quando estou usando um filtro de pesquisa. Diga <input type = "text" ng-model = "searchText" /> <li ng-repeat = "(nome, idade) nos itens | filter: searchText"> {{name}}: {{age}} </ li> ...
Shekhar
1
@Shekhar Filter "filter" funciona apenas com matrizes. Você pode tentar criar uma solicitação de recurso.
Artem Andreev 06/04
2
É bom ver algo em comum com python :)
Robert King
4
Você pode obter o recurso de filtro mesmo em dicionários (objetos) usando a instrução ng-if. Como por exemplo: <li ng-repeat = "(id, obj) nos itens" ng-if = 'obj.sex = "female "'> {{obj.name}} {{obj.surname}} </li> ... em que items é um conjunto de pessoas indexadas por alguma chave.
Giowild 17/09/14
27

Eu também gostaria de mencionar uma nova funcionalidade do AngularJSng-repeat , a saber, pontos especiais de início e fim de repetição . Essa funcionalidade foi adicionada para repetir uma série de elementos HTML em vez de apenas um elemento HTML pai único .

Para usar os pontos inicial e final do repetidor, é necessário defini-los usando ng-repeat-starte ng-repeat-enddiretivas, respectivamente.

A ng-repeat-startdiretiva funciona muito semelhante à ng-repeatdiretiva. A diferença é que isso repetirá todos os elementos HTML (incluindo a tag em que está definida) até a tag HTML final em que ng-repeat-endé colocada (incluindo a tag com ng-repeat-end).

Código de amostra (de um controlador):

// ...
$scope.users = {};
$scope.users["182982"] = {name:"John", age: 30};
$scope.users["198784"] = {name:"Antonio", age: 32};
$scope.users["119827"] = {name:"Stephan", age: 18};
// ...

Modelo HTML de amostra:

<div ng-repeat-start="(id, user) in users">
    ==== User details ====
</div>
<div>
    <span>{{$index+1}}. </span>
    <strong>{{id}} </strong>
    <span class="name">{{user.name}} </span>
    <span class="age">({{user.age}})</span>
</div>

<div ng-if="!$first">
   <img src="/some_image.jpg" alt="some img" title="some img" />
</div>
<div ng-repeat-end>
    ======================
</div>

A saída seria semelhante à seguinte (dependendo do estilo HTML):

==== User details ====
1.  119827 Stephan (18)
======================
==== User details ====
2.  182982 John (30)
[sample image goes here]
======================
==== User details ====
3.  198784 Antonio (32)
[sample image goes here]
======================

Como você pode ver, ng-repeat-startrepete todos os elementos HTML (incluindo o elemento with ng-repeat-start). Todas ng-repeatas propriedades especiais (neste caso $firste $index) também funcionam como esperado.

Tom
fonte
Erro: [$ compile: uterdir] Atributo não terminado, encontrado 'ng-repeat-start' mas não foi encontrado 'ng-repeat-end' encontrado.
Zloctb
@zloctb você deve ter pulado <div ng-repeat-end>..</div>na sua marcação
John Kaster
6

Os desenvolvedores de JavaScript tendem a se referir à estrutura de dados acima como um objeto ou hash em vez de um Dicionário.

Sua sintaxe acima está errada, pois você está inicializando o usersobjeto como nulo. Presumo que seja um erro de digitação, pois o código deve ler:

// Initialize users as a new hash.
var users = {};
users["182982"] = "...";

Para recuperar todos os valores de um hash, é necessário iterá-lo usando um loop for:

function getValues (hash) {
    var values = [];
    for (var key in hash) {

        // Ensure that the `key` is actually a member of the hash and not
        // a member of the `prototype`.
        // see: http://javascript.crockford.com/code.html#for%20statement
        if (hash.hasOwnProperty(key)) {
            values.push(key);
        }
    }
    return values;
};

Se você planeja trabalhar muito com estruturas de dados em JavaScript, a biblioteca underscore.js definitivamente vale a pena dar uma olhada. O sublinhado vem com um valuesmétodo que executará a tarefa acima para você:

var values = _.values(users);

Eu não uso o Angular, mas tenho certeza de que haverá um método de conveniência incorporado para iterar sobre os valores de um hash (ah, lá vamos nós, Artem Andreev fornece a resposta acima :))

JonnyReeves
fonte
1
+1 para underscore.js e essas informações úteis. Obrigado Johnny!
Vural
0

No Angular 7, o exemplo simples a seguir funcionaria (assumindo que o dicionário esteja em uma variável chamada d):

my.component.ts:

keys: string[] = [];  // declaration of class member 'keys'
// component code ...

this.keys = Object.keys(d);

my.component.html: (exibirá a lista de pares chave: valor)

<ul *ngFor="let key of keys">
    {{key}}: {{d[key]}}
</ul>
Ron Kalian
fonte