问题
I have a navigation bar component, a content component and a parent component that connects the two. Whenever I click on a list-item inside the navigation bar the content component shows different content by changing the booleans to false/true. That works perfectly fine, however when I try to change the content of the content component by changing the value of the @Input variable it doesn't work.
nav-admin.html
<div id="nav">
<ul class="navElement">
<li (click)="changeComponent('nutzerverwaltung')">Nutzerverwaltung</li>
<li (click)="changeComponent('branchenverwaltung')">Branchenverwaltung</li>
<li (click)="changeComponent('tarifverwaltung')">Tarifverwaltung</li>
<li (click)="changeComponent('statistiken')">Statistiken/Infos</li>
</ul>
</div>
nav-admin.ts
@Output() nutzerverwaltung = new EventEmitter<boolean>();
@Output() branchenverwaltung = new EventEmitter<boolean>();
@Output() tarifverwaltung = new EventEmitter<boolean>();
@Output() statistiken = new EventEmitter<boolean>();
@Output() changeBranchen = new EventEmitter<boolean>();
@Output() addOrEditUser = new EventEmitter<boolean>();
changeComponent(component: string): void{
if(component==='nutzerverwaltung')
{
this.nutzerverwaltung.emit(true);
this.branchenverwaltung.emit(false);
this.tarifverwaltung.emit(false);
this.statistiken.emit(false);
this.changeBranchen.emit(false);
this.addOrEditUser.emit(false);
}
else if(component==='branchenverwaltung')
{
this.branchenverwaltung.emit(true);
this.nutzerverwaltung.emit(false);
this.tarifverwaltung.emit(false);
this.statistiken.emit(false);
this.changeBranchen.emit(false);
this.addOrEditUser.emit(false);
}
....
parent.html
<app-nav-admin
(branchenverwaltung)="Pbranchenverwaltung=$event"
(nutzerverwaltung)="Pnutzerverwaltung=$event"
(tarifverwaltung)="Ptarifverwaltung=$event"
(statistiken)="Pstatistiken=$event"
(changeBranchen)="PchangeBranchen=$event"
(addOrEditUser)="PaddOrEditUser=$event"
[@slideMenu]="isVisible ? true : false"></app-nav-admin>
<app-main-admin
[branchenverwaltung]="Pbranchenverwaltung"
[nutzerverwaltung]="Pnutzerverwaltung"
[tarifverwaltung]="Ptarifverwaltung"
[statistiken]="Pstatistiken"
[changeBranchen]="PchangeBranchen"
[addOrEditUser]="PaddOrEditUser"
></app-main-admin>
parent.ts
Pbranchenverwaltung: boolean;
Pnutzerverwaltung: boolean;
Ptarifverwaltung: boolean;
Pstatistiken: boolean;
PchangeBranchen: boolean;
PaddOrEditUser: boolean;
main-admin.html (content component)
<ng-container *ngIf="nutzerverwaltung">
<button class="btnAddUser" (click)="addOrEditUserClicked()">+</button>
<table class="userTable">
<tr *ngFor="let user of users">
<td class="tableGrid">{{user.id}}</td>
<td class="tableGrid">{{user.vorname}}</td>
<td class="tableGrid">{{user.nachname}}</td>
<td class="tableGrid">{{user.telefonnummer}}</td>
<td class="tableGrid">{{user.email}}</td>
<td class="tableGrid" style="padding: 0">
<button id="btnConfigureUser" (click)="addOrEditUserClicked()">
Bearbeiten
</button>
</td>
</tr>
</table>
</ng-container>
<ng-container *ngIf="addOrEditUser">
...
</ng-container>
...
main-admin.ts (content component)
@Input() branchenverwaltung: boolean;
@Input() nutzerverwaltung: boolean;
@Input() tarifverwaltung: boolean;
@Input() statistiken: boolean;
@Input() changeBranchen: boolean;
@Input() addOrEditUser: boolean;
addOrEditUserClicked(){
this.branchenverwaltung = false;
this.nutzerverwaltung = false;
this.tarifverwaltung = false;
this.statistiken = false;
this.changeBranchen = false;
this.addOrEditUser = true;
//doesn't work
}
I'm trying to only show one , but whenever I change the value of the @Input variable inside the content component it doesn't overwrite the value. Then it shows multiple , because multiple booleans are true.
回答1:
Basically @Input decorators are used only for data which will be recieved from another component. Like you are doing before deciding to change it in the Content Component.
You can make new variables in Content Component which will be used in HTML same as @Inputs and in the common case they will be equal to the @Input variables and when you want to change some of their value like in addOrEditUserClicked() method you again change local vars (becaus they are now used in HTML).
Example: main-admin.ts (content component)
@Input() branchenverwaltung: boolean;
@Input() nutzerverwaltung: boolean;
@Input() tarifverwaltung: boolean;
@Input() statistiken: boolean;
@Input() changeBranchen: boolean;
@Input() addOrEditUser: boolean;
// Use these in HTML
let branchenverwaltungLocal: boolean;
let nutzerverwaltungLocal: boolean;
let tarifverwaltungLocal: boolean;
let statistikenLocal: boolean;
let changeBranchenLocal: boolean;
let addOrEditUserLocal: boolean;
ngOnInit() {
this.branchenverwaltungLocal= this.branchenverwaltung;
this.nutzerverwaltungLocal= this.nutzerverwaltung;
this.tarifverwaltungLocal= this.tarifverwaltung;
this.statistikenLocal= this.statistiken;
this.changeBranchenLocal= this.changeBranchen;
this.addOrEditUserLocal= this.addOrEditUser;
}
addOrEditUserClicked(){
this.branchenverwaltungLocal= false;
this.nutzerverwaltungLocal = false;
this.tarifverwaltungLocal = false;
this.statistikenLocal = false;
this.changeBranchenLocal = false;
this.addOrEditUserLocal = true;
}
Anothre tip is to use ngOnChanges method from OnChanges interface. This way if the @Input value changes by some reason from parent component you will receive the new value. Otherwise you will have only the initial one (if exist at all)
In case you are going to recieve new different @Input at some point from the parent component (NOT Your change of them in this component, but from parent) Example 2:
ngOnChanges(changes: SimpleChanges) {
if (changes) {
if (changes['branchenverwaltung'] && changes['branchenverwaltung'].currentValue !== '') {
this.branchenverwaltungLocal= this.branchenverwaltung;
}
if (changes['nutzerverwaltung'] && changes['nutzerverwaltung'].currentValue !== '') {
this.nutzerverwaltungLocal= this.nutzerverwaltung;
}
// .... and so on for the others
}
}
来源:https://stackoverflow.com/questions/57800532/is-it-possible-to-change-the-value-input-output-variables-outside-of-the-event