J'ai du mal à essayer d'utiliser Angular *ngFor
et *ngIf
sur le même élément.
Lorsque vous essayez de parcourir la collection dans le *ngFor
, la collection est vue comme null
et échoue par conséquent lorsque vous essayez d'accéder à ses propriétés dans le modèle.
@Component({
selector: 'shell',
template: `
<h3>Shell</h3><button (click)="toggle()">Toggle!</button>
<div *ngIf="show" *ngFor="let thing of stuff">
{{log(thing)}}
<span>{{thing.name}}</span>
</div>
`
})
export class ShellComponent implements OnInit {
public stuff:any[] = [];
public show:boolean = false;
constructor() {}
ngOnInit() {
this.stuff = [
{ name: 'abc', id: 1 },
{ name: 'huo', id: 2 },
{ name: 'bar', id: 3 },
{ name: 'foo', id: 4 },
{ name: 'thing', id: 5 },
{ name: 'other', id: 6 },
]
}
toggle() {
this.show = !this.show;
}
log(thing) {
console.log(thing);
}
}
Je sais que la solution simple est de *ngIf
monter d'un niveau, mais pour des scénarios tels que le bouclage des éléments de liste dans un ul
, je me retrouverais soit avec un vide li
si la collection est vide, soit avec mon li
s enveloppé dans des éléments de conteneur redondants.
Exemple à ce plnkr .
Notez l'erreur de console:
EXCEPTION: TypeError: Cannot read property 'name' of null in [{{thing.name}} in ShellComponent@5:12]
Suis-je en train de faire quelque chose de mal ou est-ce un bug?
angular
ngfor
angular-ng-if
garethdn
la source
la source
Réponses:
Angular v2 ne prend pas en charge plus d'une directive structurelle sur le même élément.
Comme solution de contournement, utilisez l'
<ng-container>
élément qui vous permet d'utiliser des éléments distincts pour chaque directive structurelle, mais il n'est pas tamponné dans le DOM .<ng-template>
(<template>
avant Angular v4) permet de faire de même mais avec une syntaxe différente qui prête à confusion et n'est plus recommandéela source
ngFor
l'<ng-container>
élément et lengIf
au<div>
. Vous pouvez également avoir deux<ng-container>
enveloppements imbriqués<div>
.<ng-container>
est juste un élément d'assistance qui ne sera pas ajouté au DOM.<ng-container>
. Il se comporte de la même manière que<template>
mais permet d'utiliser la syntaxe "normale" pour les directives structurelles.Comme tout le monde l'a souligné, même si plusieurs directives de modèle dans un seul élément fonctionnent dans angular 1.x, cela n'est pas autorisé dans Angular 2. vous pouvez trouver plus d'informations ici: https://github.com/angular/angular/issues/ 7315
2016 angular 2 beta
la solution consiste à utiliser le
<template>
comme un espace réservé, de sorte que le code va comme cecimais pour une raison quelconque ci-dessus ne fonctionne pas
2.0.0-rc.4
dans ce cas, vous pouvez utiliser ceRéponse mise à jour 2018
Avec les mises à jour, en ce moment en 2018, angulaire v6 recommande d'utiliser
<ng-container>
au lieu de<template>
voici donc la réponse mise à jour.
la source
Comme @Zyzle l'a mentionné et @ Günter mentionné dans un commentaire ( https://github.com/angular/angular/issues/7315 ), cela n'est pas pris en charge.
Avec
il n'y a aucun
<li>
élément vide lorsque la liste est vide. Même l'<ul>
élément n'existe pas (comme prévu).Lorsque la liste est remplie, il n'y a aucun élément de conteneur redondant.
La discussion github (4792) que @Zyzle a mentionnée dans son commentaire présente également une autre solution en utilisant
<template>
(ci-dessous j'utilise votre balisage d'origine - en utilisant<div>
s):Cette solution n'introduit pas non plus d'éléments de conteneur supplémentaires / redondants.
la source
<template>
est le moyen d'ajouter un élément parent qui n'apparaîtra pas dans la sortie.en html:
en css:
la source
Vous ne pouvez pas avoir
ngFor
etngIf
sur le même élément. Ce que vous pourriez faire, c'est de ne pas remplir le tableau que vous utilisezngFor
jusqu'à ce que vous cliquiez sur la bascule de votre exemple.Voici une manière basique (pas géniale) de le faire: http://plnkr.co/edit/Pylx5HSWIZ7ahoC7wT6P
la source
you can't
n'est pas vraiment une bonne réponse, n'est-ce pas?Vous ne pouvez pas utiliser plus d'un
Structural Directive
Angular sur le même élément, cela crée une mauvaise confusion et structure, vous devez donc les appliquer dans 2 éléments imbriqués distincts (ou vous pouvez utiliserng-container
), lisez cette déclaration de l'équipe Angular:Vous pouvez donc utiliser
ng-container
(Angular4) comme wrapper (sera supprimé du dom) ou div ou span si vous avez une classe ou d'autres attributs comme ci-dessous:la source
Cela fonctionnera mais l'élément sera toujours dans le DOM.
la source
Le tableau ci-dessous répertorie uniquement les éléments dont la valeur "débutant" est définie. Nécessite à la fois le
*ngFor
et le*ngIf
pour empêcher les lignes indésirables en html.A l'origine
*ngIf
et*ngFor
sur la même<tr>
balise, mais ne fonctionne pas. Ajout d'un<div>
pour la*ngFor
boucle et placé*ngIf
dans la<tr>
balise, fonctionne comme prévu.la source
<div>
intérieur d'une table soit une idée de goos, surtout quand il existe de meilleures alternatives. Avez-vous vérifié si cela fonctionne donc dans IE, qui est particulièrement pointilleux sur les éléments dans<table>
Mise à jour vers angular2 beta 8
Maintenant, depuis angular2 beta 8, nous pouvons utiliser
*ngIf
et*ngFor
sur le même composant voir ici .Alterner:
Parfois, nous ne pouvons pas utiliser de balises HTML dans une autre comme dans
tr
,th
(table
) ou dansli
(ul
). Nous ne pouvons pas utiliser une autre balise HTML, mais nous devons effectuer une action dans la même situation afin que nous puissions utiliser la balise de fonctionnalité HTML5<template>
de cette manière.ngPour utiliser le modèle:
ngSi vous utilisez un modèle:
Pour plus d'informations sur les directives structurelles dans angular2, voir ici .
la source
la source
Vous pouvez également utiliser
ng-template
(au lieu du modèle. Voir la remarque pour la mise en garde de l'utilisation de la balise de modèle) pour appliquer à la fois * ngFor et ngIf sur le même élément HTML. Voici un exemple où vous pouvez utiliser à la fois * ngIf et * ngFor pour le même élément tr dans le tableau angulaire.où
fruiArray = ['apple', 'banana', 'mango', 'pineapple']
.Remarque:
La mise en garde d'utiliser uniquement la
template
balise au lieu de lang-template
balise est qu'elle jetteStaticInjectionError
à certains endroits.la source
la source
Vous ne pouvez pas utiliser plusieurs directives structurelles sur le même élément. Enveloppez votre élément
ng-template
et utilisez une directive structurellela source
Vous pouvez le faire d'une autre manière en vérifiant la longueur du tableau
la source
app.component.ts
app.component.html
Production
la source