Ich habe ein Problem mit dem Versuch, Angulars *ngFor
und *ngIf
dasselbe Element zu verwenden.
Beim Versuch, die Sammlung in der zu durchlaufen *ngFor
, wird die Sammlung als angezeigt null
und schlägt folglich fehl, wenn versucht wird, auf ihre Eigenschaften in der Vorlage zuzugreifen.
@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);
}
}
Ich weiß, dass die einfache Lösung darin besteht, die *ngIf
Ebene nach oben zu verschieben, aber für Szenarien wie das Durchlaufen von Listenelementen in a ul
würde ich entweder leer sein, li
wenn die Sammlung leer ist, oder meine li
s in redundante Containerelemente verpackt.
Beispiel bei diesem plnkr .
Beachten Sie den Konsolenfehler:
EXCEPTION: TypeError: Cannot read property 'name' of null in [{{thing.name}} in ShellComponent@5:12]
Mache ich etwas falsch oder ist das ein Fehler?
angular
ngfor
angular-ng-if
garethdn
quelle
quelle
Antworten:
Angular v2 unterstützt nicht mehr als eine Strukturanweisung für dasselbe Element.
Verwenden
<ng-container>
Sie als Problemumgehung das Element, mit dem Sie für jede Strukturanweisung separate Elemente verwenden können, das jedoch nicht in das DOM gestempelt ist .<ng-template>
(<template>
vor Angular v4) ermöglicht es, dasselbe zu tun, jedoch mit einer anderen Syntax, die verwirrend ist und nicht mehr empfohlen wirdquelle
ngFor
auf das<ng-container>
Element und dasngIf
auf das setzen<div>
. Sie können auch zwei verschachtelte<ng-container>
Wraps haben<div>
.<ng-container>
ist nur ein Hilfselement, das dem DOM nicht hinzugefügt wird.<ng-container>
. Es verhält sich genauso<template>
, erlaubt jedoch die Verwendung der "normalen" Syntax für strukturelle Anweisungen.Wie alle betonten, ist es in Angular 2 nicht zulässig, mehrere Template-Direktiven in einem einzelnen Element in Angular 1.x zu haben. Weitere Informationen finden Sie hier: https://github.com/angular/angular/issues/ 7315
2016 Winkel 2 Beta
Die Lösung besteht darin, das
<template>
als Platzhalter zu verwenden, damit der Code so aussiehtaber aus irgendeinem Grund funktioniert oben nicht
2.0.0-rc.4
in diesem Fall können Sie dies verwendenAktualisierte Antwort 2018
Mit Updates empfehlen wir ab sofort im Jahr 2018 die Verwendung
<ng-container>
von Angular V6 anstelle von<template>
Hier ist die aktualisierte Antwort.
quelle
Wie @Zyzle und @ Günter in einem Kommentar ( https://github.com/angular/angular/issues/7315 ) erwähnt haben, wird dies nicht unterstützt.
Mit
Es gibt keine leeren
<li>
Elemente, wenn die Liste leer ist. Auch das<ul>
Element existiert nicht (wie erwartet).Wenn die Liste ausgefüllt ist, gibt es keine redundanten Containerelemente.
Die Github-Diskussion (4792) , die @Zyzle in seinem Kommentar erwähnt hat, präsentiert auch eine andere Lösung mit
<template>
(unten verwende ich Ihr ursprüngliches Markup - mit<div>
s):Diese Lösung führt auch keine zusätzlichen / redundanten Containerelemente ein.
quelle
<template>
Auf diese Weise können Sie ein übergeordnetes Element hinzufügen, das in der Ausgabe nicht angezeigt wird.in html:
in css:
quelle
Sie können nicht
ngFor
undngIf
auf dem gleichen Element haben. Sie können das Auffüllen des Arrays, in dem Sie sich befinden, so lange aufhalten,ngFor
bis Sie auf den Schalter in Ihrem Beispiel klicken.Hier ist eine grundlegende (nicht großartige) Möglichkeit, dies zu tun: http://plnkr.co/edit/Pylx5HSWIZ7ahoC7wT6P
quelle
you can't
nicht wirklich eine gute Antwort, stimmst du nicht zu?Sie können
Structural Directive
in Angular nicht mehr als eines für dasselbe Element verwenden.ng-container
Dies führt zu einer schlechten Verwirrung und Struktur. Sie müssen sie daher in zwei separaten verschachtelten Elementen anwenden (oder Sie können sie verwenden ). Lesen Sie diese Anweisung des Angular-Teams:Sie können also
ng-container
(Angular4) als Wrapper (wird aus dem Dom gelöscht) oder als Div oder Span verwenden, wenn Sie eine Klasse oder andere Attribute wie folgt haben:quelle
Dies funktioniert, aber das Element befindet sich weiterhin im DOM.
quelle
In der folgenden Tabelle sind nur Elemente aufgeführt, für die ein "Anfänger" -Wert festgelegt wurde. Erfordert sowohl das
*ngFor
als auch das*ngIf
, um unerwünschte Zeilen in HTML zu verhindern.Ursprünglich hatte
*ngIf
und*ngFor
auf dem gleichen<tr>
Tag, funktioniert aber nicht. Ein<div>
for für die*ngFor
Schleife hinzugefügt und*ngIf
in das<tr>
Tag eingefügt, funktioniert wie erwartet.quelle
<div>
Tisch in einem Tisch eine gute Idee ist, besonders wenn es bessere Alternativen gibt. Haben Sie überprüft, ob dies in IE funktioniert, was besonders wählerisch in Bezug auf Elemente in<table>
Auf Angular2 Beta 8 aktualisiert
Ab Angular2 Beta 8 können wir nun dieselbe Komponente verwenden
*ngIf
und hier sehen .*ngFor
Wechseln:
Manchmal können wir keine HTML-Tags in anderen wie in
tr
,th
(table
) oder inli
(ul
) verwenden. Wir können kein anderes HTML-Tag verwenden, müssen jedoch in derselben Situation eine Aktion ausführen, damit wir das HTML5-Feature-Tag<template>
auf diese Weise ausführen können .ngFür die Verwendung der Vorlage:
ngWenn Sie eine Vorlage verwenden:
Weitere Informationen zu Strukturrichtlinien in Angular2 finden Sie hier .
quelle
quelle
Sie können auch
ng-template
(anstelle der Vorlage. Siehe den Hinweis zur Einschränkung der Verwendung des Vorlagen-Tags) zum Anwenden von * ngFor und ngIf auf dasselbe HTML-Element verwenden. Hier ist ein Beispiel, in dem Sie sowohl * ngIf als auch * ngFor für dasselbe tr- Element in der Winkeltabelle verwenden können .wo
fruiArray = ['apple', 'banana', 'mango', 'pineapple']
.Hinweis:
Die Einschränkung, nur das
template
Tag anstelle desng-template
Tags zu verwenden, besteht darin, dass esStaticInjectionError
an einigen Stellen ausgelöst wird .quelle
quelle
Sie können nicht mehrere strukturelle Anweisungen für dasselbe Element verwenden. Wickeln Sie Ihr Element ein
ng-template
und verwenden Sie dort eine strukturelle Richtliniequelle
Sie können dies auch auf andere Weise tun, indem Sie die Array-Länge überprüfen
quelle
app.component.ts
app.component.html
Ausgabe
quelle