我有三个组成部分。一个父组件(dashboard.component.ts),其中包含两个兄弟姐妹(poll-form.component.ts和poll.component.ts)。其中一个兄弟,轮询组件将Output()发送回父级,称为(editEvent)=“ editPoll($ event)”。发送此Output()时,我希望在另一个同级poll-form.component内部触发一个函数,而不是在父级dashboard.component中触发该函数。正确的方法是什么?
我当前的实现“有点”工作。它在父级中触发该函数,然后父级导入该组件并在同级组件中调用该函数。但是,问题在于兄弟姐妹组件会跳过ngOnInit(),并且无法访问函数中所需的组件变量。
最终,我想将表单分解成自己的组件,但是打开表单的动作是由同级组件触发的。
dashboard.component.html
<div class="page">
<div style="margin-bottom: 20px; margin-right: 20px; text-align: left;">
<button type="button" (click)="showCreateModal()" pButton icon="pi pi-check" label="Create Poll"></button>
</div>
<div *ngFor="let pollId of pollIds" style="display: inline-block;">
<app-poll [pollKey]="pollId" (editEvent)="editPoll($event)" (deleteEvent)="deletePoll($event)"></app-poll>
</div>
</div>
<div *ngIf="displayCreateModal">
<app-poll-form [type]="'create'" (closeEvent)="closeModal($event)"></app-poll-form>
</div>
<div *ngIf="displayEditModal">
<app-poll-form [type]="'edit'" (closeEvent)="closeModal($event)"></app-poll-form>
</div>
poll.component.ts
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import * as Chart from 'chart.js';
import { Observable } from 'rxjs';
import { FirebaseService } from '../services/firebase.service';
import { first } from 'rxjs/operators';
import { CardModule } from 'primeng/card';
import { AngularFireAuth } from '@angular/fire/auth';
@Component({
selector: 'app-poll',
templateUrl: './poll.component.html',
styleUrls: ['./poll.component.scss']
})
export class PollComponent implements OnInit {
poll:any;
@Input()
pollKey: string;
@Output()
editEvent = new EventEmitter<string>();
constructor(private firebaseService: FirebaseService, private afAuth: AngularFireAuth) { }
ngOnInit() {
this.firebaseService.getPoll(this.pollKey).subscribe(pollDoc => {
if (!pollDoc.payload.exists) {
return;
}
const pollData:any = pollDoc.payload.data();
this.poll = {
id: pollDoc.payload.id,
helperText: pollData.helperText,
pollType: pollData.pollType,
scoringType: pollData.scoringType,
user: pollData.user
};
}
edit() {
this.editEvent.emit(this.poll);
}
}
poll-form.component.ts
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { DialogModule } from 'primeng/dialog';
import { DropdownModule } from 'primeng/dropdown';
import { AutoCompleteModule } from 'primeng/autocomplete';
import { SelectButtonModule } from 'primeng/selectbutton';
import { FirebaseService } from '../services/firebase.service';
import nflPlayers from '../../assets/data/players-nfl.json';
import nflPollTypes from '../../assets/types/poll-types-nfl.json';
import nflScoringTypes from '../../assets/types/scoring-types-nfl.json';
@Component({
selector: 'app-poll-form',
templateUrl: './poll-form.component.html',
styleUrls: ['./poll-form.component.scss']
})
export class PollFormComponent implements OnInit {
title:string;
btnLabel:string;
selectedScoringType:any;
choices:any;
selectedPollType:any;
selectedPollKey:any;
displayEditModal:boolean = false;
displayCreateModal:boolean = false;
filteredPlayersMultiple: any[];
displayModal:boolean = true;
nflPlayers:any = nflPlayers.Players;
nflPollTypes:any = nflPollTypes.types;
nflScoringTypes:any = nflScoringTypes.types;
activePlayers:any;
@Input()
type: string;
@Output()
closeEvent = new EventEmitter<string>();
constructor(
private firebaseService: FirebaseService
) { }
ngOnInit() {
this.initFormDefaults();
}
initFormDefaults() {
this.choices = [[],[]];
this.selectedScoringType = this.nflScoringTypes[0];
this.selectedPollType = this.nflPollTypes[0];
if (this.type == "create") {
this.btnLabel = "Create";
this.title = "Create Poll";
} else {
this.btnLabel = "Update";
this.title = "Edit Poll";
}
// Filter out active NFL players
this.activePlayers = this.nflPlayers.filter(player => player.active == "1");
}
editPoll(poll) {
this.type = "edit"
this.activePlayers = this.nflPlayers.filter(player => player.active == "1");
this.selectedPollKey = poll.id;
// Set scoring type
this.selectedScoringType = this.nflScoringTypes.find((type) => {
return type.code == poll.scoringType
});
// Set poll type
this.selectedPollType = this.nflPollTypes.find((type) => {
return type.code == poll.pollType
});
// Populate edit modal with properly formatted Player objects
for (let i=0; i < poll.choices.length; i++) {
this.choices[i] = poll.choices[i].players.map((choicePlayer:any) => {
return this.activePlayers.find(player => player.playerId == choicePlayer.id);
});
}
}
}
dashboard.component.ts
import { Component, OnInit } from '@angular/core';
import { AngularFireAuth } from '@angular/fire/auth';
import { first } from 'rxjs/operators';
import { Observable } from 'rxjs';
import { PollFormComponent } from '../poll-form/poll-form.component';
@Component({
providers: [PollFormComponent],
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.scss']
})
export class DashboardComponent implements OnInit {
displayEditModal:boolean = false;
constructor(
private pollFormComponent: PollFormComponent
) { }
ngOnInit() {
}
editPoll(poll) {
this.displayEditModal = true;
this.pollFormComponent.editPoll(poll);
}
}