Вызов метода из внукового компонента в угловых 7 - PullRequest
0 голосов
/ 30 мая 2019

У меня есть приложение angular 7 и я пытаюсь вызвать метод Parent из его внукового компонента. У меня есть Модальный Компонент, который является большим дочерним компонентом. Я пытаюсь вызвать метод оттуда. Я вызываю тот же метод от его непосредственного родителя, используя выходное событие, которое работает но как мне позвонить от внука.

Я объявил Событие

 @Output() termDetailsEvent = new EventEmitter<string>();

И так вызвать родительский метод
this.termDetailsEvent.next('getTermsDetails');

Родительский компонент

import { Component, OnInit, Input, ViewChild } from '@angular/core';
import { TermsService } from '../services/terms.service';
import { FundClassesComponent } from './fundClasses/fundClasses.component';


@Component({
    selector: 'mgr-terms',
    templateUrl: 'terms.component.html'
})


export class TermsComponent implements OnInit {

    private Error: string;
    public TermDetails: any;
    private _ManagerStrategyId: number;
    FilteredClasses: any;
    OriginalList: any;
    Funds: any;
    FundClassType: any;
    FirmFunds: any;
    public get ManagerStrategyId(): number {
        return this._ManagerStrategyId;
    }

    @ViewChild(FundClassesComponent)
    fundClassesComponent: FundClassesComponent;

    @Input()
    public set ManagerStrategyId(value: number) {
        this._ManagerStrategyId = value;
    }
    FundClasses: any;
    LegalFundClasses: any;
    originalFundClasses: any;
    constructor(private termsService: TermsService) { }

    ngOnInit() {
        this.init();
    }

    init() {
        this.getTermsDetails();
    }


    public getTermsDetails() {
        if (this.ManagerStrategyId != null) {
            this.termsService.getTermsDetails(this.ManagerStrategyId).subscribe((data: any) => {
                this.TermDetails = data;
                this.OriginalList = JSON.parse(JSON.stringify(data));
                this.FundClasses = this.TermDetails.FundClassViewModel;
                this.LegalFundClasses = this.TermDetails.LegalFundClassViewModel;
                this.Funds = this.TermDetails.LegalFundClassViewModel.Funds;
                this.FundClassType = this.TermDetails.LegalFundClassViewModel.FundClassType;
                this.FirmFunds = this.TermDetails.LegalFundClassViewModel.FirmFunds;

                this.TermDetails.FundClassViewModel.FundDetailsViewModel.forEach(funDetail=> {
                    funDetail.FundClassDetailsViewModel = funDetail.FundClassDetailsViewModel
                        .reduce((prev, next) => prev = prev.concat(next), [])
                        .filter(obj => obj.InvestedAmount !== null);
                });


            });
        }
    }
}

Родительский компонент html

<mgr-fund-classes (termDetailsEvent)="getFundInvestedDetails($event)" [FundClasses]="FundClasses" ></mgr-fund-classes>
<br/>
<br/>
<mgr-legal-fund-classes  (termDetailsEvent)="getTermsDetails()" [Funds] = "Funds" [FundClassType] = "FundClassType" [LegalFundClasses]="LegalFundClasses" [FirmFunds] ="FirmFunds" ></mgr-legal-fund-classes>

дочерний компонент

import { Component, OnInit, Input, ViewChild, Output, EventEmitter } from '@angular/core';
import { TermsService } from '../../services/terms.service';
import { NotifyService } from '../../utilities/notify.service';
import { number } from '@amcharts/amcharts4/core';
import { IReview } from '../terms.interface';
import { AddLegalFundClassComponent } from './addLegalFundClass.component';
import { AddSideLetterComponent } from './addSideLetter.component';
import { CloneLegalFundClassComponent } from './cloneLegalFundClass.component';


@Component({
    selector: 'mgr-legal-fund-classes',
    templateUrl: './legalFundClasses.component.html'
})



export class LegalFundClassesComponent implements OnInit {

    private _legalFundClasses: any;
    LegalFundClass: any;

    @Output() termDetailsEvent = new EventEmitter<string>();


    public get LegalFundClasses(): any {
        return this._legalFundClasses;
    }
    @Input()
    public set LegalFundClasses(value: any) {
        this._legalFundClasses = value;
    }



    public defaultItem: { Name: string, Id: number } = { Name: "Select item...", Id: null };

    constructor(private termsService: TermsService, private notify: NotifyService) { }

    ngOnInit() {
        this.init();
    }


    public value: any = [{ Id: null, Name: "" }];



    Update(id) {
        this.LegalFundClass = this.LegalFundClasses.LegalFundClassDetailsViewModel
              .find(obj => obj.Id === id);

        this.termsService.updateLegalFundClasses(this.LegalFundClass).then((result) => {
            if (result) {
                this.notify.success('Legal Fund Class Details Successfully Updated');
                this.EditMode[id] = !this.EditMode[id];
                this.termDetailsEvent.next('getTermsDetails');
            }
        }).catch(err => {
            this.notify.error('An Error Has Occured While Updating Legal Fund Class Details');
        });
    }

    Delete(id) {

        this.termsService.deleteLegalFundClasses(id).then((result) => {
            if (result) {
                this.notify.success('Legal Fund Class Successfully Deleted');
                this.EditMode = !this.EditMode[id];
                this.termDetailsEvent.next('getTermsDetails');
            }
        }).catch(err => {
            this.notify.error('An Error Has Occured While Deleting Fund Class Details');
        });
    }


Child component html

<shared-modal [modalSize]="1" class="survey-edit" [open]="cloneLegalFundClassWindowOpened">
<div style="width: 100%;" header>
    <h4 class="modal-title">
        <div style="text-align: right"><button aria-label="Dismiss" class="close" style="margin-top: -10px"
                type="button" (click)="dismissCloneModal()">X</button>
        </div>
    </h4>
</div>
<div body>
    <app-clone-legalclass  (termDetailsEvent)="getTermsDetails()" [FirmFunds]="FirmFunds"></app-clone-legalclass>

</div>
<div footer>
</div>

Большой дочерний компонент

export class CloneLegalFundClassComponent implements OnInit {

    private Error: string;
    public ManagerDetails: any;
    public EditorConfig: string;
    public CloneLegalFundClass: ICloneLegalFundClass;

    @Input() FirmFunds: any;
    @Output() termDetailsEvent = new EventEmitter<string>();

    constructor(private termsService: TermsService, private notify: NotifyService) {
    }

    ngOnInit() {

        this.CloneLegalFundClass = { Description: '', Id: null, FundId: null };
    }


    cloneLegalFundClass() {
        this.CloneLegalFundClass.FundId = this.FirmFunds.find(x => x.Id === this.CloneLegalFundClass.Id).FundId;
        this.termsService.cloneLegalFundClasses(this.CloneLegalFundClass).then((result) => {
            if (result) {
                this.notify.success('Legal Fund Class Cloned Successfully');
                this.termDetailsEvent.next('getTermsDetails');
            }
        }).catch(err => {
            this.notify.error('An Error Has Occured While cloning Legal Fund Class');
        });
    }

    closeLegalFundClass() {

    }
}

1 Ответ

1 голос
/ 30 мая 2019

Я создал простой Stackblitz, показывающий, как это сделать. Вы просто продолжаете излучать дальше: https://stackblitz.com/edit/angular-ad4kf3

Внук тс:

    import { Component, Output, EventEmitter, OnInit } from '@angular/core';
import { timer } from 'rxjs';


@Component({
  selector: 'app-grandchild',
  templateUrl: './grandchild.component.html',
  styleUrls: ['./grandchild.component.css']
})
export class GrandchildComponent implements OnInit {
  @Output() emitToChild: EventEmitter<void> = new EventEmitter();
  constructor() { }

  ngOnInit() {
    // emitting to child every two seconds, check console
    this.emit();
  }

  emit() {
    this.emitToChild.emit();
    timer(2000).subscribe(() => this.emit());
  }
}

Внук HTML:

<p>I'm grandchild.</p>

Детский TS:

import { Component, OnInit, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
  @Output() emitToParent: EventEmitter<void> = new EventEmitter();
  constructor() { }

  ngOnInit() {
  }

}

дочерний HTML:

<p>I'm child.</p>
<app-grandchild (emitToChild)="emitToParent.emit()"></app-grandchild>

Parent TS:

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {

  doSomething() {
    console.log('hello');
  }
}

Родительский HTML:

<p>I'm Parent</p>

<app-child (emitToParent)="doSomething()"></app-child>
...