【发布时间】:2019-10-16 06:08:20
【问题描述】:
我有一个 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');
});
}
子组件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>
</shared-modal>
子组件
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() {
}
}
【问题讨论】:
-
你可以嵌套@Output()。当孙子向孩子发射时,只需让孩子向其父母发射。如果您有多个方法,则需要以这种方式调用服务可能是更好的方法。
-
如果我采用非服务方法,我的实施有什么问题
-
没有错 - 只是如果应用程序增长,可能很难跟踪执行的内容。
-
但我目前的问题是我无法从孙子组件调用。我没有看到父组件触发
-
尝试使用 .emit 而不是 .next
标签: angular angular-controller angular-observable