typescript 从父类调用子组件方法- Angular

qij5mzcb  于 2023-11-20  发布在  TypeScript
关注(0)|答案(9)|浏览(212)

我已经创建了一个子组件,它有一个我想调用的方法。
当我调用这个方法时,它只触发console.log()行,它不会设置test属性??
下面是快速启动Angular应用程序与我的变化。

父级

  1. import { Component } from '@angular/core';
  2. import { NotifyComponent } from './notify.component';
  3. @Component({
  4. selector: 'my-app',
  5. template:
  6. `
  7. <button (click)="submit()">Call Child Component Method</button>
  8. `
  9. })
  10. export class AppComponent {
  11. private notify: NotifyComponent;
  12. constructor() {
  13. this.notify = new NotifyComponent();
  14. }
  15. submit(): void {
  16. // execute child component method
  17. notify.callMethod();
  18. }
  19. }

字符串

孩子

  1. import { Component, OnInit } from '@angular/core';
  2. @Component({
  3. selector: 'notify',
  4. template: '<h3>Notify {{test}}</h3>'
  5. })
  6. export class NotifyComponent implements OnInit {
  7. test:string;
  8. constructor() { }
  9. ngOnInit() { }
  10. callMethod(): void {
  11. console.log('successfully executed.');
  12. this.test = 'Me';
  13. }
  14. }


如何设置test属性?

carvr3hs

carvr3hs1#

您可以通过使用@ViewChild来完成此操作。更多信息请查看此link

带类型选择器

辅元件

  1. @Component({
  2. selector: 'child-cmp',
  3. template: '<p>child</p>'
  4. })
  5. class ChildCmp {
  6. doSomething() {}
  7. }

字符串
父组件

  1. @Component({
  2. selector: 'some-cmp',
  3. template: '<child-cmp></child-cmp>',
  4. directives: [ChildCmp]
  5. })
  6. class SomeCmp {
  7. @ViewChild(ChildCmp) child:ChildCmp;
  8. ngAfterViewInit() {
  9. // child is set
  10. this.child.doSomething();
  11. }
  12. }

带字符串选择器

辅元件

  1. @Component({
  2. selector: 'child-cmp',
  3. template: '<p>child</p>'
  4. })
  5. class ChildCmp {
  6. doSomething() {}
  7. }


父组件

  1. @Component({
  2. selector: 'some-cmp',
  3. template: '<child-cmp #child></child-cmp>',
  4. directives: [ChildCmp]
  5. })
  6. class SomeCmp {
  7. @ViewChild('child') child:ChildCmp;
  8. ngAfterViewInit() {
  9. // child is set
  10. this.child.doSomething();
  11. }
  12. }

展开查看全部
368yc8dk

368yc8dk2#

我认为最简单的方法是使用Subject。在下面的示例代码中,每次调用'tellChild()'时都会通知孩子。

Parent.component.ts

  1. import {Subject} from 'rxjs/Subject';
  2. ...
  3. export class ParentComp {
  4. changingValue: Subject<boolean> = new Subject();
  5. tellChild() {
  6. this.changingValue.next(true);
  7. }
  8. }

字符串

Parent.component.html

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

Child.component.ts

  1. ...
  2. export class ChildComp implements OnInit{
  3. @Input() changing: Subject<boolean>;
  4. ngOnInit(){
  5. this.changing.subscribe(v => {
  6. console.log('value is changing', v);
  7. });
  8. }
  9. }


Stackblitz上的工作样本

展开查看全部
yfwxisqw

yfwxisqw3#

这对我很有用!对于Angular 2,在父组件中调用子组件方法

Parent.component.ts

  1. import { Component, OnInit, ViewChild } from '@angular/core';
  2. import { ChildComponent } from '../child/child';
  3. @Component({
  4. selector: 'parent-app',
  5. template: `<child-cmp></child-cmp>`
  6. })
  7. export class parentComponent implements OnInit{
  8. @ViewChild(ChildComponent ) child: ChildComponent ;
  9. ngOnInit() {
  10. this.child.ChildTestCmp(); }
  11. }

字符串

Child.component.ts

  1. import { Component } from '@angular/core';
  2. @Component({
  3. selector: 'child-cmp',
  4. template: `<h2> Show Child Component</h2><br/><p> {{test }}</p> `
  5. })
  6. export class ChildComponent {
  7. test: string;
  8. ChildTestCmp()
  9. {
  10. this.test = "I am child component!";
  11. }
  12. }

展开查看全部
k5ifujac

k5ifujac4#

Angular -在父组件的模板中调用子组件的方法
你有ParentComponent和ChildComponent,看起来像这样。
parent.component.html
x1c 0d1x的数据
parent.component.ts

  1. import {Component} from '@angular/core';
  2. @Component({
  3. selector: 'app-parent',
  4. templateUrl: './parent.component.html',
  5. styleUrls: ['./parent.component.css']
  6. })
  7. export class ParentComponent {
  8. constructor() {
  9. }
  10. }

字符串
child.component.html

  1. <p>
  2. This is child
  3. </p>


child.component.ts

  1. import {Component} from '@angular/core';
  2. @Component({
  3. selector: 'app-child',
  4. templateUrl: './child.component.html',
  5. styleUrls: ['./child.component.css']
  6. })
  7. export class ChildComponent {
  8. constructor() {
  9. }
  10. doSomething() {
  11. console.log('do something');
  12. }
  13. }


当服务时,它看起来像这样:



当用户关注ParentComponent的input元素时,您希望调用ChildComponent的doSomething()方法。
只需这样做:
1.给予parent.component.html中的app-child选择器一个DOM变量名**(前缀为# - hashtag)**,在本例中我们称之为appChild。
1.为输入元素的焦点事件分配表达式值(您要调用的方法的值)。



结果:


展开查看全部
txu3uszq

txu3uszq5#

parent.component.html

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

字符串
parent.component.ts

  1. @Component({
  2. selector: 'app-parent',
  3. templateUrl: './app-parent.component.html',
  4. styleUrls: ['./app-parent.component.scss']
  5. })
  6. export class ParentComponent {
  7. @ViewChild('childComponent', {static: false}) childComponent: ChildComponent;
  8. anyMethod(): void {
  9. childComponent.updateData() // updateData is a child method
  10. }
  11. }


child.component.ts

  1. @Component({
  2. selector: 'app-child',
  3. templateUrl: './app-child.component.html',
  4. styleUrls: ['./app-child.component.scss']
  5. })
  6. export class ChildComponent {
  7. updateData(): void {
  8. // Method code goes here
  9. }
  10. }

展开查看全部
ql3eal8s

ql3eal8s6#

user6779899的答案是简洁和更通用的。然而,根据Imad El Hitti的要求,这里提出了一个轻量级的解决方案。这可以在子组件仅与一个父组件紧密连接时使用。

Parent.component.ts

  1. export class Notifier {
  2. valueChanged: (data: number) => void = (d: number) => { };
  3. }
  4. export class Parent {
  5. notifyObj = new Notifier();
  6. tellChild(newValue: number) {
  7. this.notifyObj.valueChanged(newValue); // inform child
  8. }
  9. }

字符串

Parent.component.html

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

Child.component.ts

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

展开查看全部
aamkag61

aamkag617#

考虑以下示例,

  1. import import { AfterViewInit, ViewChild } from '@angular/core';
  2. import { Component } from '@angular/core';
  3. import { CountdownTimerComponent } from './countdown-timer.component';
  4. @Component({
  5. selector: 'app-countdown-parent-vc',
  6. templateUrl: 'app-countdown-parent-vc.html',
  7. styleUrl: [app-countdown-parent-vc.css]
  8. })
  9. export class CreateCategoryComponent implements OnInit, AfterViewInit {
  10. @ViewChild(CountdownTimerComponent, {static: false}) private timerComponent: CountdownTimerComponent;
  11. ngAfterViewInit() {
  12. this.timerComponent.startTimer();
  13. }
  14. submitNewCategory(){
  15. this.ngAfterViewInit();
  16. }
  17. }

字符串
阅读更多关于@ViewChild这里.

展开查看全部
9o685dep

9o685dep8#

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

父级.HTML:

  1. <form (ngSubmit)='selX' [formGroup]="xSelForm">
  2. <select formControlName="xSelector">
  3. ...
  4. </select>
  5. <button type="submit">Submit</button>
  6. </form>
  7. <child [selectedX]="selectedX"></child>

字符串

父TS:

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

子TS:

  1. export class ChildComponent implements OnChanges {
  2. @Input() public selectedX;
  3. //ngOnChanges will execute if there is a change in the value of selectedX which has been passed to child as an @Input.
  4. ngOnChanges(changes: { [propKey: string]: SimpleChange }) {
  5. this.childFunction();
  6. }
  7. childFunction(){ }
  8. }


希望这对你有帮助。

展开查看全部
zphenhs4

zphenhs49#

我用EventEmitter来做这个。

parent.component.ts

  1. @Component({
  2. selector: "app-parent",
  3. template: '<app-child listener="notify"></app-child>' +
  4. '<button (click)="notify.emit()">Call child function</button>',
  5. //...
  6. })
  7. export class ParentComponent {
  8. notify: EventEmitter<void> = new EventEmitter<void>()
  9. }

字符串

child.component.ts

  1. @Component({
  2. selector: "app-child",
  3. template: "<i>Child component text</i>",
  4. //...
  5. })
  6. export class ChildComponent {
  7. #listener: EventEmitter<void> = new EventEmitter<void>()
  8. @Input()
  9. set listener(emitter: EventEmitter<void>) {
  10. this.#listener.unsubscribe()
  11. this.#listener = emitter
  12. this.#listener.subscribe(this.childFunction.bind(this))
  13. }
  14. childFunction() {
  15. console.log("Child function called")
  16. }
  17. }


这种方法的优点:

  • reliable -即使您稍后在代码中更改EventEmitterParentComponent中的notify属性值),也可以正常工作
  • 保持组件解耦

坏的部分:

  • 与其他解决方案相比,

如果需要传递一些数据,请将void(在EventEmitter<void>中)替换为所需的类型。
如果你需要传递一个以上的参数,那么我建议创建interface,并将数据作为一个对象传递,其中包含你需要传递给ChildComponent的所有参数。更快(也更脏)的解决方案是将类型设置为any,并传递你想要的任何对象。

传入对象作为参数的示例

parent.component.ts

  1. @Component({
  2. selector: "app-parent",
  3. template: '<app-child listener="notify"></app-child>' +
  4. '<button (click)="callChild()">Call child function</button>',
  5. //...
  6. })
  7. export class ParentComponent {
  8. notify: EventEmitter<any> = new EventEmitter<any>()
  9. callChild() {
  10. this.notify.emit({title: 'Parent call', id: 1})
  11. }
  12. }

child.component.ts

  1. @Component({
  2. selector: "app-child",
  3. template: "<i>Child component text</i>",
  4. //...
  5. })
  6. export class ChildComponent {
  7. #listener: EventEmitter<any> = new EventEmitter<any>()
  8. @Input()
  9. set listener(emitter: EventEmitter<any>) {
  10. this.#listener.unsubscribe()
  11. this.#listener = emitter
  12. this.#listener.subscribe(this.childFunction.bind(this))
  13. }
  14. childFunction(data: any) {
  15. console.log("Child function called")
  16. console.log(data)
  17. }
  18. }

展开查看全部

相关问题