부모 클래스에서 자식 구성 요소 메서드 호출-Angular


130

호출하려는 메서드가있는 자식 구성 요소를 만들었습니다.

이 메서드를 호출하면 console.log()줄만 실행 하고 test속성을 설정하지 않습니까 ??

아래는 변경 사항이 적용된 빠른 시작 Angular 앱입니다.

부모의

import { Component } from '@angular/core';
import { NotifyComponent }  from './notify.component';

@Component({
    selector: 'my-app',
    template:
    `
    <button (click)="submit()">Call Child Component Method</button>
    `
})
export class AppComponent {
    private notify: NotifyComponent;

    constructor() { 
      this.notify = new NotifyComponent();
    }

    submit(): void {
        // execute child component method
        notify.callMethod();
    }
}

아이

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

@Component({
    selector: 'notify',
    template: '<h3>Notify {{test}}</h3>'
})
export class NotifyComponent implements OnInit {
   test:string; 
   constructor() { }

    ngOnInit() { }

    callMethod(): void {
        console.log('successfully executed.');
        this.test = 'Me';
    }
}

test속성도 어떻게 설정할 수 있습니까?



이 답변은 여기에서 확인할 수 있습니다. stackoverflow.com/a/53057589/6663458
Muhammad Mabrouk

답변:


210

다음을 사용하여이 작업을 수행 할 수 있습니다 @ViewChild더 많은 정보 확인이에 대한 링크

유형 선택기 포함

하위 구성 요소

@Component({
  selector: 'child-cmp',
  template: '<p>child</p>'
})
class ChildCmp {
  doSomething() {}
}

상위 구성 요소

@Component({
  selector: 'some-cmp',
  template: '<child-cmp></child-cmp>',
  directives: [ChildCmp]
})
class SomeCmp {

  @ViewChild(ChildCmp) child:ChildCmp;

  ngAfterViewInit() {
    // child is set
    this.child.doSomething();
  }
}

문자열 선택기 사용

하위 구성 요소

@Component({
  selector: 'child-cmp',
  template: '<p>child</p>'
})
class ChildCmp {
  doSomething() {}
}

상위 구성 요소

@Component({
  selector: 'some-cmp',
  template: '<child-cmp #child></child-cmp>',
  directives: [ChildCmp]
})
class SomeCmp {

  @ViewChild('child') child:ChildCmp;

  ngAfterViewInit() {
    // child is set
    this.child.doSomething();
  }
}

6
귀하의 접근 방식을 따랐지만 지시문을 사용하는 동안 오류가 발생했습니다 : [ChildCmp], 오류 메시지 : 지시문 '이'구성 요소 '유형에 없습니다. 나는 그것을 봤고 지시문이 rc5에서 더 이상 사용되지 않는다는 것을 발견했습니다. 따라서 최신 버전에서 처리하는 방법. 도와주세요.
Waleed Shahzaib

1
이 링크 시도 angular.io/guide/component-interaction을 하고 지시 링크 논평
rashfmnb

5
같은 학급의 여러 자녀가있을 때 어떻게 작동하게 만들까요 ??
Anandhu Ajayakumar

@rashfmnb "선언이 필요합니다". 구성 요소에 @ViewChild ( 'child') child : ChildCmp;를 쓰려고 할 때 오류가 발생합니다. 도와주세요! 또한 지시문에서 동일한 내용을 가져올 수 없습니다. "지시문 : (employeeProfileC ..."유형은 '구성 요소'유형의 매개 변수에 할당 할 수 없습니다. '구성 요소'유형에 존재합니다. "
Trilok Pathak

1
이것은 정답이지만 밀접하게 결합 된 구성 요소를 생성 합니다 . 더 나은 패턴은 Input속성 을 사용 하는 것입니다. 자식이 자체 내부 함수를 호출하여 반응하는 관찰 가능 항목 입니다. user6779899 님의 답변보기
Bogdan D

56

이것은 나를 위해 일했습니다! Angular 2의 경우 부모 구성 요소에서 자식 구성 요소 메서드 호출

Parent.component.ts

    import { Component, OnInit, ViewChild } from '@angular/core';
    import { ChildComponent } from '../child/child'; 
    @Component({ 
               selector: 'parent-app', 
               template: `<child-cmp></child-cmp>` 
              }) 
    export class parentComponent implements OnInit{ 
        @ViewChild(ChildComponent ) child: ChildComponent ; 

        ngOnInit() { 
           this.child.ChildTestCmp(); } 
}

Child.component.ts

import { Component } from '@angular/core';
@Component({ 
  selector: 'child-cmp', 
  template: `<h2> Show Child Component</h2><br/><p> {{test }}</p> ` 
})
export class ChildComponent {
  test: string;
  ChildTestCmp() 
  { 
    this.test = "I am child component!"; 
  }
 }


4
이 줄에서 ChildVM은 무엇입니까? @ViewChild (ChildComponent) child : ChildVM;
Waleed Shahzaib

@WaleedShahzaib OP가 의미 ChildComponent하는 것 같아요ChildVM
Ajeet Shah

1
나는 이것이 구성 요소의 별도 인스턴스를 만들 것이라고 생각했지만 실제로는 해당 구성 요소의 현재 상태 인 신성한 암소의 변수를 사용하여 인스턴스에서 함수를 호출합니다! 이 방법은 첫 번째 답변보다 훨씬 낫습니다!
tatsu

3
난 항상 "this.child"의 정의되지 않은 값 얻고있다
Ambuj 칸나

2
'this.child'가 정의되지 않은 것에 대한 내 추측은 ViewChild가 템플릿에 존재하지 않는 것을 가리 키거나 생성자에서와 같이 수명주기에서 너무 일찍 액세스하려고한다는 것입니다.
tony

34

가장 쉬운 방법은 Subject를 사용하는 것입니다. 아래 예제 코드에서 'tellChild'가 호출 될 때마다 자녀에게 알림이 전송됩니다.

Parent.component.ts

import {Subject} from 'rxjs/Subject';
...
export class ParentComp {
    changingValue: Subject<boolean> = new Subject();
    tellChild(){
    this.changingValue.next(true);
  }
}

Parent.component.html

<my-comp [changing]="changingValue"></my-comp>

Child.component.ts

...
export class ChildComp implements OnInit{
@Input() changing: Subject<boolean>;
ngOnInit(){
  this.changing.subscribe(v => { 
     console.log('value is changing', v);
  });
}

Stackblitz의 작업 샘플


4
우아한 솔루션이지만 모든 경우에 제대로 작동하지 않습니다. 아마도 구독에서 각도 변경 감지가 작동하지 않기 때문일 것입니다.
Alexei

1
이것이 내 사용 사례에 가장 적합한 솔루션이라는 것을 알았습니다. 매력처럼 작동합니다. 감사!
Weston

깔끔한! 더 간단한 경우에는 콜백 메서드가있는 개체를 자식에게 전달하여 Subject / Subscribe 오버 헤드를 피할 수 있습니다. 위와 유사하게 자식은 콜백을 재정 의하여 부모로부터 표시를받습니다.
shr

@shr 콜백으로 객체를 전달하는 솔루션을 공유 할 수 있습니까?
Imad El Hitti

1
이것은 우아한 해결책입니다. 이것은 받아 들여진 대답이어야합니다. import {Subject} from 'rxjs';
VIKAS KOHLI

5

Angular – 부모 구성 요소의 템플릿에서 자식 구성 요소의 메서드 호출

다음과 같은 ParentComponent 및 ChildComponent가 있습니다.

parent.component.html

여기에 이미지 설명 입력

parent.component.ts

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

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

child.component.html

<p>
  This is child
</p>

child.component.ts

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

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

  doSomething() {
    console.log('do something');
  }
}

제공 할 때 다음과 같이 보입니다.

여기에 이미지 설명 입력

사용자가 ParentComponent의 입력 요소에 초점을 맞출 때 ChildComponent의 doSomething () 메서드를 호출하려고합니다.

다음과 같이하십시오.

  1. parent.component.html의 app-child 선택기에 DOM 변수 이름 (접두사 # – hashtag) 을 지정합니다.이 경우 appChild라고합니다.
  2. 호출하려는 메서드의 식 값을 입력 요소의 포커스 이벤트에 할당합니다.

여기에 이미지 설명 입력

결과:

여기에 이미지 설명 입력



구성 요소 내에서 사용 : @ViewChild('appChild', { static: false }) appChild: ElementRef<HTMLElement>;이후 사용this.appChild.doSomething()
Gil Epshtain

4

user6779899의 답변은 깔끔하고 일반적이지만 Imad El Hitti의 요청에 따라 여기에서 경량 솔루션이 제안되었습니다. 자식 구성 요소가 하나의 부모에만 단단히 연결되어있을 때 사용할 수 있습니다.

Parent.component.ts

export class Notifier {
    valueChanged: (data: number) => void = (d: number) => { };
}

export class Parent {
    notifyObj = new Notifier();
    tellChild(newValue: number) {
        this.notifyObj.valueChanged(newValue); // inform child
    }
}

Parent.component.html

<my-child-comp [notify]="notifyObj"></my-child-comp>

Child.component.ts

export class ChildComp implements OnInit{
    @Input() notify = new Notifier(); // create object to satisfy typescript
    ngOnInit(){
      this.notify.valueChanged = (d: number) => {
            console.log(`Parent has notified changes to ${d}`);
            // do something with the new value 
        };
    }
 }

2

다음 예를 고려하십시오.

    import import { AfterViewInit, ViewChild } from '@angular/core';
    import { Component } from '@angular/core';
    import { CountdownTimerComponent }  from './countdown-timer.component';
    @Component({
        selector: 'app-countdown-parent-vc',
        templateUrl: 'app-countdown-parent-vc.html',
        styleUrl: [app-countdown-parent-vc.css]
    export class CreateCategoryComponent implements OnInit {
         @ViewChild(CountdownTimerComponent, {static: false})
         private timerComponent: CountdownTimerComponent;
         ngAfterViewInit() {
             this.timerComponent.startTimer();
         }

         submitNewCategory(){
            this.ngAfterViewInit();     
         }

여기에서 @ViewChild 에 대해 자세히 알아 보세요.


0

부모-컴포넌트가 Select폼에 요소를 가지고 있고 제출할 때 선택 요소에서 선택된 값에 따라 관련 자식-컴포넌트의 메서드를 호출해야하는 정확한 상황이있었습니다 .

Parent.HTML :

<form (ngSubmit)='selX' [formGroup]="xSelForm">
    <select formControlName="xSelector">
      ...
    </select>
<button type="submit">Submit</button>
</form>
<child [selectedX]="selectedX"></child>

Parent.TS :

selX(){
  this.selectedX = this.xSelForm.value['xSelector'];
}

Child.TS :

export class ChildComponent implements OnChanges {
  @Input() public selectedX;

  //ngOnChanges will execute if there is a change in the value of selectedX which has been passed to child as an @Input.

  ngOnChanges(changes: { [propKey: string]: SimpleChange }) {
    this.childFunction();
  }
  childFunction(){ }
}

도움이 되었기를 바랍니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.