Вызов метода дочерних компонентов из родительского класса - Angular

Я создал дочерний компонент, у которого есть метод, который я хочу вызвать.

Когда я вызываю этот метод, он запускает только строку 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?

Ответ 1

Вы можете сделать это, используя @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();
  }
}

Ответ 2

Это сработало для меня! Для 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!"; 
  }
 }

Ответ 3

Я думаю, что самый простой способ - использовать тему. В приведенном ниже примере кода ребенок будет уведомляться каждый раз, когда вызывается 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

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 
        };
    }
 }

Ответ 5

Angular - вызов метода дочерних компонентов в шаблоне родительских компонентов

У вас есть ParentComponent и ChildComponent, который выглядит следующим образом.

parent.component.html

enter image description here

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');
  }
}

Когда подают, это выглядит так:

enter image description here

Когда пользователь фокусируется на элементе ввода ParentComponents, вы хотите вызвать метод ChildComponents doSomething().

Просто сделайте это:

  1. Дайте селектору app-child в parent.component.html имя переменной DOM (префикС# - хэштег), в этом случае мы называем его appChild.
  2. Присвойте значение выражения (метода, который вы хотите вызвать) для ввода события фокуса элемента.

enter image description here

Результат:

enter image description here