我有一个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() {
}
}
答案 0 :(得分:1)
我创建了一个简单的Stackblitz,展示了如何做。您只是继续发出更多信息: https://stackblitz.com/edit/angular-ad4kf3
孙子ts:
ffmpeg version n3.0.1 Copyright (c) 2000-2016 the FFmpeg developers built with gcc 4.8 (GCC)
configuration:
--target-os=linux
--cross-prefix=/home/vagrant/SourceCode/ffmpeg-android/toolchain-android/bin/arm-linux-androideabi-
--arch=arm
--cpu=cortex-a8
--enable-runtime-cpudetect
--sysroot=/home/vagrant/SourceCode/ffmpeg-android/toolchain-android/sysroot
--enable-pic
--enable-libx264
--enable-libass
--enable-libfreetype
--enable-libfribidi
--enable-libmp3lame
--enable-fontconfig
--enable-pthreads
--disable-debug
--disable-ffserver
--enable-version3
--enable-hardcoded-tables
--disable-ffplay
--disable-ffprobe
--enable-gpl
--enable-yasm
--disable-doc
--disable-shared
--enable-static
--pkg-config=/home/vagrant/SourceCode/ffmpeg-android/ffmpeg-pkg-config
--prefix=/home/vagrant/SourceCode/ffmpeg-android/build/armeabi-v7a
--extra-cflags='-I/home/vagrant/SourceCode/ffmpeg-android/toolchain-android/include -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fno-strict-overflow -fstack-protector-all'
--extra-ldflags='-L/home/vagrant/SourceCode/ffmpeg-android/toolchain-android/lib -Wl,-z,relro -Wl,-z,now -pie'
--extra-libs='-lpng -lexpat -lm'
--extra-cxxflags=
libavutil 55. 17.103 / 55. 17.103
libavcodec 57. 24.102 / 57. 24.102
libavformat 57. 25.100 / 57. 25.100
libavdevice 57. 0.101 / 57. 0.101
libavfilter 6. 31.100 / 6. 31.100
libswscale 4. 0.100 / 4. 0.100
libswresample 2. 0.101 / 2. 0.101
libpostproc 54. 0.100 / 54. 0.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/storage/emulated/0/DCIM/Yakatak/656.mp4': Metadata: major_brand : mp42 minor_version : 0 compatible_brands: isommp42 creation_time : 2019-05-29 11:27:56 location : +51.5202-000.1435/ location-eng : +51.5202-000.1435/ Duration: 00:00:09.47, start: 0.000000, bitrate: 12147 kb/s Stream #0:0(eng): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p, 1280x720, 11899 kb/s, 30.02 fps, 30 tbr, 90k tbn, 180k tbc (default) Metadata: rotate : 90 creation_time : 2019-05-29 11:27:56 handler_name : VideoHandle Side data: displaymatrix: rotation of -90.00 degrees Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 256 kb/s (default) Metadata: creation_time : 2019-05-29 11:27:56 handler_name : SoundHandle[libx264 @ 0xb5428800] using cpu capabilities: none![libx264 @ 0xb5428800] profile Constrained Baseline, level 3.1[libx264 @ 0xb5428800] 264 - core 148 - H.264/MPEG-4 AVC codec - Copyleft 2003-2015 - http://www.videolan.org/x264.html - options: cabac=0 ref=1 deblock=0:0:0 analyse=0:0 me=dia subme=0 psy=1 psy_rd=1.00:0.00 mixed_ref=0 me_range=16 chroma_me=1 trellis=0 8x8dct=0 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=0 threads=6 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=0 weightp=0 keyint=250 keyint_min=25 scenecut=0 intra_refresh=0 rc=crf mbtree=0 crf=32.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=0
Output #0, mp4, to '/storage/emulated/0/DCIM/Yakatak/uploadFile.mp4': Metadata: major_brand : mp42 minor_version : 0 compatible_brands: isommp42 location-eng : +51.5202-000.1435/ location : +51.5202-000.1435/ encoder : Lavf57.25.100 Stream #0:0(eng): Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv420p, 720x1280, q=-1--1, 30 fps, 15360 tbn, 30 tbc (default) Metadata: handler_name : VideoHandle creation_time : 2019-05-29 11:27:56 encoder : Lavc57.24.102 libx264 Side data: unknown side data type 10 (24 bytes) Stream #0:1(eng): Audio: aac (LC) ([64][0][0][0] / 0x0040), 48000 Hz, stereo, fltp, 128 kb/s (default) Metadata: creation_time : 2019-05-29 11:27:56 handler_name : SoundHandle encoder : Lavc57.24.102 aacStream mapping: Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264)) Stream #0:1 -> #0:1 (aac (native) -> aac (native))Press [q] to stop, [?] for helpframe= 0 fps=0.0
孙子HTML:
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());
}
}
儿童TS:
<p>I'm grandchild.</p>
子HTML:
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() {
}
}
父母TS:
<p>I'm child.</p>
<app-grandchild (emitToChild)="emitToParent.emit()"></app-grandchild>
父HTML:
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
doSomething() {
console.log('hello');
}
}