Estou tentando fazer algumas coisas no Angular 2 Alpha 28 e estou tendo um problema com dicionários e NgFor.
Eu tenho uma interface no TypeScript parecida com esta:
interface Dictionary {
[ index: string ]: string
}
Em JavaScript, isso será traduzido para um objeto que, com dados, será assim:
myDict={'key1':'value1','key2':'value2'}
Quero iterar sobre isso e tentei o seguinte:
<div *ngFor="(#key, #value) of myDict">{{key}}:{{value}}</div>
Mas sem sucesso, nenhum dos itens abaixo funcionou:
<div *ngFor="#value of myDict">{{value}}</div>
<div *ngFor="#value of myDict #key=index">{{key}}:{{value}}</div>
Em todos os casos, recebo erros como "Token inesperado" ou "Não é possível encontrar o objeto de suporte de tubo 'iterableDiff'"
O que estou perdendo aqui? Isso não é mais possível? (A primeira sintaxe funciona no Angular 1.x) ou a sintaxe é diferente para iterar sobre um objeto?
Respostas:
Parece que eles não querem dar suporte à sintaxe de ng1.
De acordo com Miško Hevery ( referência ):
Portanto, para percorrer seu objeto, você precisará usar um "pipe". Atualmente, não há canal implementado que faça isso.
Como solução alternativa, aqui está um pequeno exemplo que itera sobre as chaves:
Componente:
fonte
key
asnumber
evalue
asstring
mas angular está jogando erroexpression has changed after it was checked
? por que alguma idéia?Resposta Angular 6.1.0+
Use o
keyvalue
tubo integrado assim:ou assim:
onde
mySortingFunction
está no seu.ts
arquivo, por exemplo:Stackblitz: https://stackblitz.com/edit/angular-iterate-key-value
Você não precisará registrar isso em nenhum módulo, pois os tubos angulares funcionam de maneira imediata em qualquer modelo.
Também funciona para Javascript-Maps .
fonte
implements PipeTransform
na definição de classe (ver angular.io/guide/pipes#custom-pipes )return Object.keys(dict).map(key => ({key, val: dict[key]}))
?tente usar esse tubo
fonte
Além da resposta do @ obscur, aqui está um exemplo de como você pode acessar o
key
e avalue
partir do @View.Tubo:
Visão:
Portanto, se o objeto fosse parecido com:
O resultado gerado seria:
Nome: Daario
Sobrenome: Naharis
Primeiro nome: Victarion
Sobrenome: Greyjoy
Nome: Quentyn
Sobrenome: Ball
fonte
<li *ngFor="let u of myObject | keyValueFilter">First Name: {{u.key}} <br> Last Name: {{u.value}}</li>
. +1 de mim.return { 'key' : key, 'value' : value[key] };
Atualizado em: Angular agora está fornecendo o pipe para percorrer o objeto json via
keyvalue
:DEMONSTRAÇÃO DE TRABALHO , e para mais detalhes Leia
Anteriormente (para a versão mais antiga): Até agora, a melhor / menor resposta que encontrei é (sem filtro de tubulação ou função personalizada do lado do componente)
DEMONSTRAÇÃO DE TRABALHO
fonte
let item of myDict | keyvalue
isso resolveu meu problema.Adicionando ao SimonHawesome excelente resposta de . Fiz uma versão sucinta que utiliza alguns dos novos recursos datilografados. Percebo que a versão de SimonHawesome é intencionalmente detalhada para explicar os detalhes subjacentes. Também adicionei uma verificação antecipada para que o pipe funcione com valores falsos . Por exemplo, se o mapa estiver
null
.Observe que o uso de uma transformação de iterador (como feito aqui) pode ser mais eficiente, pois não precisamos alocar memória para uma matriz temporária (como feito em algumas das outras respostas).
fonte
PipeTransform
Aqui está uma variação de algumas das respostas acima que oferecem suporte a várias transformações (keyval, key, value):
Uso
fonte
pure: false
é realmente importante para reflexões instantâneas.Eu tive um problema semelhante, construí algo para objetos e mapas.
fonte
implements PipeTransform
à definição de classeAngular 2.x e& Angular 4.x não suportam isso imediatamente
Você pode usar esses dois canais para iterar por chave ou por valor .
Tubo de chaves:
Tubo de valores:
Como usar:
fonte
Se alguém está se perguntando como trabalhar com objetos multidimensionais, aqui está a solução.
vamos assumir que temos o seguinte objeto em serviço
no componente adicione a seguinte função
finalmente, tendo em vista o seguinte
fonte
Tenho arrancado os cabelos tentando analisar e usar os dados retornados de uma chamada JSON query / api. Não sei exatamente onde estava errado, sinto que tenho circulado a resposta por dias, perseguindo vários códigos de erro como:
"Não foi possível encontrar o objeto de suporte do tubo 'iterableDiff'"
"Matriz TYpe genérica requer um ou mais argumentos"
Erros de análise de JSON e tenho certeza que outros
Estou assumindo que apenas tive a combinação errada de correções.
Então, aqui está um resumo de dicas e coisas para procurar.
Em primeiro lugar, verifique o resultado de suas chamadas de API, seus resultados podem estar na forma de um objeto, uma matriz ou uma matriz de objetos.
eu não vou falar muito sobre isso, basta dizer que o erro original do OP de não ser iterável geralmente é causado por você tentar iterar um objeto, não uma matriz.
Heres alguns dos meus resultados de depuração mostrando variáveis de matrizes e objetos
Portanto, como geralmente queremos iterar sobre nosso resultado JSON, precisamos garantir que ele esteja na forma de uma matriz. Tentei vários exemplos e, talvez, sabendo o que sei agora, alguns deles realmente funcionariam, mas a abordagem com que eu fui foi realmente implementar um pipe e o código que usei foi o postado por t.888
Sinceramente, acho que uma das coisas que me motivou foi a falta de tratamento de erros. Ao adicionar a chamada 'return undefined', acredito que agora estamos permitindo que dados não esperados sejam enviados ao canal, o que obviamente estava ocorrendo no meu caso .
se você não quiser lidar com argumentos para o canal (e veja, eu acho que não é necessário na maioria dos casos), basta retornar o seguinte
Algumas notas sobre como criar seu canal e página ou componente que usa esse canal
é que eu estava recebendo erros sobre 'nome_do_meu_pipe' não sendo encontrado
Use o comando 'ionic generate pipe' da CLI para garantir que os pipes.ts sejam criados e referenciados corretamente. verifique se você adicionou o seguinte à página mypage.module.ts.
(não tenho certeza se isso muda se você também tiver seu próprio custom_module, talvez seja necessário adicioná-lo ao custommodule.module.ts)
se você usou o comando 'ionic generate page' para criar sua página, mas decide usar essa página como sua página principal, lembre-se de remover a referência da página do app.module.ts (aqui está outra resposta que eu postei sobre esse https: / /forum.ionicframework.com/t/solved-pipe-not-found-in-custom-component/95179/13?u=dreaser
Na minha busca por respostas, há várias maneiras de exibir os dados no arquivo html, e eu não entendo o suficiente para explicar as diferenças. Você pode achar melhor usar um sobre o outro em certos cenários.
No entanto, o que funcionou que me permitiu exibir o valor e a chave foi o seguinte:
para fazer a chamada da API, parece que você precisa importar o HttpModule para app.module.ts
e você precisa de Http na página da qual faz a ligação
Ao fazer a chamada da API, parece que você consegue acessar os dados filhos (os objetos ou as matrizes dentro da matriz) de 2 maneiras diferentes, que parecem funcionar
durante a chamada
ou quando você atribui os dados à sua variável local
(não tenho certeza se essa variável precisa ser uma String de matriz, mas é isso que eu tenho agora. Pode funcionar como uma variável mais genérica)
E nota final, não foi necessário usar a biblioteca JSON embutida, no entanto, você pode encontrar essas 2 chamadas úteis para converter de um objeto em uma string e vice-versa
Espero que esta compilação de informações ajude alguém.
fonte
fonte
As interfaces no TypeScript são uma construção de tempo de desenvolvimento (apenas para ferramentas ... 0 impacto no tempo de execução). Você deve escrever o mesmo TypeScript que o seu JavaScript.
fonte
O dicionário é um objeto, não uma matriz. Acredito que ng-repeat requer uma matriz no Angular 2.
A solução mais simples seria criar um tubo / filtro que converta o objeto em uma matriz em tempo real. Dito isto, você provavelmente deseja usar uma matriz como o @basarat diz.
fonte
Se você tem
es6-shim
ou seutsconfig.json
destinoes6
, você pode usar o ES6 Map para fazê-lo.fonte
Defina
MapValuesPipe
e implemente o PipeTransform :Adicione seu tubo no seu módulo de tubos. Isso é importante se você precisar usar o mesmo tubo em mais de um componente :
Em seguida, basta usar o pipe no seu html com
*ngFor
:<tr *ngFor="let attribute of mMap | mapValuesPipe">
Lembre-se, você precisará declarar seu PipesModule no componente em que deseja usar o pipe:
fonte
Então, eu iria implementar minha própria função auxiliar, objLength (obj), que retorna apenas Object (obj) .keys.length. Mas quando o adicionei à função template * ngIf, meu IDE sugeriu objectKeys (). Eu tentei e funcionou. Após a declaração, ela parece ser oferecida pelo lib.es5.d.ts, então pronto!
Aqui está como eu o implementei (eu tenho um objeto personalizado que usa chaves geradas no servidor como um índice para arquivos que eu enviei):
fonte