Wenn Sie dynamisch erstellte Komponenten in Angular verwenden, fällt es Ihnen wahrscheinlich schwer, bei Bedarf Informationen zwischen den übergeordneten und untergeordneten Komponenten weiterzugeben. Sie müssen die Informationen in der übergeordneten Komponente bereitstellen und diese dann in die untergeordnete Komponente einfügen. Obwohl dies nicht unbedingt schwierig ist, führt es zu einer Menge zusätzlichen Standardcodes.
Es wäre viel besser, wenn wir einfach den @Input
Dekorator verwenden könnten, wie wir es gewohnt sind. Rate mal? Angular unterstützt genau dies ab Version 16. In diesem Beitrag zeige ich Ihnen wie. Okay, lasst uns loslegen.
Schauen wir uns zunächst an, wie wir früher Daten vom übergeordneten Element an dynamisch erstellte Komponenten übergeben haben. Hier, in diesem Beispiel, haben wir innerhalb der Komponentenvorlage unser *ngComponentOutlet
und übergeben es an unsere Player-Komponente.
In diesem Fall übergeben wir auch einen benutzerdefinierten untergeordneten Injektor, und auf diese Weise würden wir zuvor die Daten für die untergeordnete Komponente injizieren.
@Component({ selector: 'app-root', template: ` <ng-container *ngComponentOutlet="playerComponent; injector: childInjector"></ng-container> ` }) export class App { protected playerComponent = PlayerComponent; }
Und um diesen untergeordneten Injektor zu erstellen, mussten wir eine Eigenschaft erstellen, damit sie festgelegt und dann innerhalb der Vorlage verwendet werden konnte.
export class App { protected childInjector?: Injector; ... }
Dann mussten wir den Injektor aus dem Winkelkern innerhalb des Konstruktors injizieren.
export class App { ... constructor(private injector: Injector) { } }
Danach mussten wir den untergeordneten Injektor mithilfe der Methode „create“ und des Provider-Arrays festlegen, um dem untergeordneten Element unser Spieler-Token bereitzustellen.
export class App { ... constructor(private injector: Injector) { this.childInjector = Injector.create({ providers: [ { provide: PlayerToken, useValue: this.player } ], parent: this.injector }); } }
Und schließlich mussten wir in der untergeordneten Komponente, unserer Player-Komponente, unsere Player-Eigenschaft mit der Injektionsmethode aus dem Winkelkern festlegen.
export class PlayerComponent { protected player?: Player = inject(PlayerToken); }
Bei all dem geht es also nur darum, ein einfaches Player-Objekt an eine dynamische Komponente zu übergeben. Ich meine, wenn dies keine dynamische Komponente wäre, würden wir daraus einfach einen @Input
machen und das Spielerdatenobjekt einfach an den @Input
im übergeordneten Element binden. Aber das ist eine dynamisch erstellte Komponente, also können wir das nicht machen, oder?
Nun, ab Angular sixteen können wir stattdessen tatsächlich @Input
s verwenden, und das ist viel einfacher als das, was wir bisher gesehen haben.
*ngComponentOutlet
Inputs-Objekts Wir beginnen stattdessen damit, diese Spielereigenschaft in einen @Input
zu ändern. Und es wird einfach in unsere Player-Oberfläche eingegeben.
export class PlayerComponent { @Input() player?: Player; }
Jetzt können wir die Injektionsmethode und Spieler-Token-Importe entfernen, da sie nicht mehr benötigt werden. Dann können wir, zurück in unserem übergeordneten Objekt, in der Vorlage den Injektor entfernen und ihn stattdessen durch ein Eingabeobjekt ersetzen. Wir können dieses Objekt an beliebig viele Eingaben übergeben. Wenn wir also fünf Eingaben hätten, würden wir einfach deren Namen einschließen und dann jeder Eingabe die von uns benötigten Daten übergeben.
Aber in diesem Fall haben wir nur eine Eingabe für unsere untergeordnete Komponente, den Player, also ist das alles, was wir brauchen, um sie zu übergeben.
@Component({ selector: 'app-root', template: ` <ng-container *ngComponentOutlet="playerComponent; inputs: { player }"></ng-container> ` })
Jetzt können wir den Kinderinjektor entfernen. Das heißt, wir können den Konstruktor auch ganz entfernen. Und schließlich können wir den Injector aus dem Angular Core und den Player-Token-Import entfernen, da wir sie nicht mehr verwenden.
export class App { protected player: Player = { name: 'LeBron James', games: 1421, points: 38652, fieldGoalPercentage: 0.505, threePointPercentage: 0.345, imageName: 'lebron-james' }; protected playerComponent = PlayerComponent; }
Und das ist es. Wir können sehen, dass alles genauso funktioniert wie früher. Es ist also um einiges einfacher umzusetzen und erfordert auch weniger Code, was immer großartig ist.
Ein Nachteil ist jedoch, dass @Input
s zwar unterstützt werden, @Output
s jedoch nicht. Irgendwie schade, aber es ist, was es ist. Hoffentlich werden sie in Zukunft Unterstützung hinzufügen, da dies auch sehr praktisch wäre, aber wir müssen einfach abwarten und sehen.
Schauen Sie sich den Democode und Beispiele dieser Techniken im folgenden Stackblitz-Beispiel an. Wenn Sie Fragen oder Gedanken haben, zögern Sie nicht, einen Kommentar zu hinterlassen.