Angular.JS 中从父类调用子组件方法

我已经创建了一个子组件,其中有一个我想调用的方法。

当我调用这个方法时,它只触发console.log()行,它不会设置test属性??

下面是我修改后的Angular快速入门应用。

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


@Component({
selector: 'my-app',
template:
`

`
})
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: '

Notify {{test}}

' }) export class NotifyComponent implements OnInit { test:string; constructor() { } ngOnInit() { } callMethod(): void { console.log('successfully executed.'); this.test = 'Me'; } }

如何设置test属性呢?

351716 次浏览

你可以通过使用@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();
}
}

这对我很管用!对于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!";
}
}

我认为最简单的方法是使用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上的工作示例

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

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

当用户关注ParentComponent的input元素时,你需要调用ChildComponent的doSomething()方法。

简单地这样做:

    给parent.component.html中的app-child selector一个DOM变量名 ,在本例中我们称它为appChild。
  1. 将表达式值(要调用的方法的值)赋给输入元素的焦点事件。

enter image description here

结果:

enter image description here

考虑下面的例子:

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, AfterViewInit {
@ViewChild(CountdownTimerComponent, {static: false}) private timerComponent: CountdownTimerComponent;
ngAfterViewInit() {
this.timerComponent.startTimer();
}


submitNewCategory(){
this.ngAfterViewInit();
}
}

点击这里阅读更多关于@ViewChild的信息

我有一个确切的情况,父组件在表单中有一个Select元素,在提交时,我需要根据从选择元素中选择的值调用相关的子组件的方法。

Parent.HTML:

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

的父母。TS:

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

的孩子。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(){ }
}

希望这能有所帮助。

parent.component.html

<app-child #childComponent></app-child>

parent.component.ts

@Component({
selector: 'app-parent',
templateUrl: './app-parent.component.html',
styleUrls: ['./app-parent.component.scss']
})
export class ParentComponent {
@ViewChild('childComponent', {static: false}) childComponent: ChildComponent;


anyMethod(): void {
childComponent.updateData() // updateData is a child method
}
}

child.component.ts

@Component({
selector: 'app-child',
templateUrl: './app-child.component.html',
styleUrls: ['./app-child.component.scss']
})
export class ChildComponent {
updateData(): void {
// Method code goes here
}
}