Angular 7-从同级发送Output()后,在同级组件内部调用函数

时间:2019-04-10 19:10:15

标签: javascript angular typescript

我有三个组成部分。一个父组件(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);
  }

}

0 个答案:

没有答案