Comment passer la variable actuelle dans une boucle ngFor à ngIf, si elle utilise des modèles avec la syntaxe then/else?
Il semble qu'ils passent bien lorsqu'ils sont utilisés en ligne, mais ne sont pas accessibles à partir d'un modèle, par exemple:
<ul *ngFor="let number of numbers">
<ng-container *ngIf="number % 2 == 0; then even_tpl; else odd_tpl"><>/ng-container>
</ul>
<ng-template #odd_tpl>
<li>Odd: {{number}}</li>
</ng-template>
<ng-template #even_tpl>
<li>Even: {{number}}</li>
</ng-template>
Les modèles ne semblent pas du tout avoir accès à number
, mais cela fonctionne s'ils sont utilisés en ligne.
Un exemple complet des versions de travail et non fonctionnel dans le lien suivant: plunkr
Il vous suffit d'utiliser [ngTemplateOutletContext]
En savoir plus
Voici comment vous pouvez y parvenir:
<div>
<h3>All Templates</h3>
<ul *ngFor="let number of numbers">
<ng-container [ngTemplateOutlet]='number % 2 == 0 ? even_tpl : odd_tpl' [ngTemplateOutletContext]="{number:number}"></ng-container>
</ul>
</div>
<ng-template #odd_tpl let-number='number'>
<li>Odd: {{number}}</li>
</ng-template>
<ng-template #even_tpl let-number='number'>
<li>Even: {{number}}</li>
</ng-template>
regardez ici: Passer la variable dans Angular 2
<div *ngFor="foo in foos">
<ng-container *ngTemplateOutlet="inner; context:{name:foo}"></ng-container>
</div>
<ng-template #inner let-name="name">
{{ name }}
</ng-template>
C'est parce que la façon dont la portée du modèle fonctionne. Les modèles dans Angular ont une portée dynamique au lieu d'une portée lexicale javascript régulière, cela signifie que le {{ number }}
expression à l'intérieur du ng-template
ne pointe pas vers la même variable number
dans votre *ngFor
, bien que l'on devrait penser que ce serait le cas puisque vous êtes un peu évaluation l'expression du modèle où <ng-container>
est.
Si vous définissez réellement une propriété number
dans votre AppComponent
, disons number = 42
, vous pouvez voir que tous les {{number}}
expressions à l'intérieur <ng-template>
correspond à 42
.
Vous devez donc définir vos modèles dans le cadre de *ngFor
, où la variable number
a la valeur souhaitée, ou transmet cette valeur aux deux even_tpl
et odd_tpl
. Comme l'a souligné @Vivek, vous pouvez le faire avec ngTemplateOutlet
et ngTemplateOutletContext
.
Voici quelques options (similaires) supplémentaires pour plusieurs arguments, celui-ci comprend l'utilisation de 'ngTemplateOutletContext' et également une condition (dans le 4ème argument - pour le plaisir).
... devrait fonctionner par copier-coller ...
<!-- DEMO using:
"=templateID; context:{prop:value, ...}"
( 4 arguments demo)
Note: $implicit identifies the default argument in the template.
The template does not need to assign the argument name,
- see the 3rd argument
-->
<div *ngFor="let item of ['Aaa', 'Bbb', 'Ccc']; index as ix">
<ng-container *ngTemplateOutlet="myTemplate1;
context:{cDemoName:'Option 1:',
cIx:ix+1,
$implicit:item,
cIsEven: ((ix % 2) === 0) ? 'true' : 'false' }">
</ng-container>
</div>
<hr>
<!-- DEMO using:
[ngTemplateOutlet]="templateID"
[ngTemplateOutletContext]="{"=templateID; context:{prop:value, ...}"
-->
<div *ngFor="let item of ['Dddd', 'Eee', 'Fff']; index as ix">
<ng-container [ngTemplateOutlet]="myTemplate1"
[ngTemplateOutletContext]="{
cDemoName:'Option 2',
cIx:ix+1,
$implicit:item,
cIsEven: ((ix % 2) === 0) ? 'true' : 'false' }
">
</ng-container>
</div>
<!-- DEMO template:
( 4 arguments expected)
-->
<ng-template #myTemplate1
let-cDemoName="cDemoName"
let-cIx="cIx"
let-cItem
let-cIsEven="cIsEven">
Context arguments demo name: {{cDemoName}} <br>
. . . . . Context index: {{cIx}} <br>
. . . . . Context item: --- {{ cItem }} --- <br>
. . . . . Context is-even: {{ cIsEven }} <br>
<br>
</ng-template>