在两个子组件之间共享方法(角度)

时间:2020-01-17 15:36:35

标签: javascript angular typescript

组件的结构如下:

enter image description here

期望的行为

child1_component-是标题。

child2_component-是一个身体。

child1_component内有一个按钮。

点击该按钮,我想在child2_component内调用一个方法。

问题

实现此目标的最佳方法是什么?

3 个答案:

答案 0 :(得分:2)

一种解决方法是使用带有rxjs主题和可观察对象的服务。

  1. 当用户单击child1_component中的按钮时,它会调用一个方法,该方法又会在共享服务内部调用一个方法。

  2. 调用服务中的方法时,它可以通过主题发出可观察的值。

  3. 然后,
  4. child2_component订阅共享服务中的可观察对象,并可以根据何时从服务接收数据来操作某些逻辑。

此处提供有关服务的更多信息:https://angular.io/tutorial/toh-pt4

关于主题和rxjs的出色教程:https://blog.angulartraining.com/rxjs-subjects-a-tutorial-4dcce0e9637f

答案 1 :(得分:0)

有两种方法可以做到:

1.Service:

    export class ActionService {
      private someAction = new Subject();


      someActionEmitted$(): Observable<unknown> {
        return this.someAction.asObservable();
      }

      emitSomeAction(): void {
        this.someAction.next();
      }
    }


    //childComponent1
    export class ChildComponent1 {
      constructor(private actionService: ActionService) {
      }

      emitAction(): void {
        this.actionService.emitSomeAction();
      }
    }

    //childComponent2
    export class ChildComponent2 implements OnInit, OnDestroy {
      private destroy$ = new Subject();

      constructor(private actionService: ActionService) {
      }

      ngOnInit(): void {
        this.actionService.someActionEmitted$()
          .pipe(takeUntil(this.destroy$))  // dont forget to unsubscribe, can cause memory leaks
          .subscribe(() => this.doSomething());
      }

      doSomething(): void {
        // your logic here
      }

      ngOnDestroy(): void {
        this.destroy$.next();
      }
    }

2。使用父组件

<child-component1 (btnClicked)="childComponentBtnClick()"></child-component1> <child-component2 [clickBtnSubject]="childBtnClicked"></child-component1>

Ts逻辑:

export class ParentComponent {
  childBtnClicked = new Subject();

  childComponentBtnClick(): void {
    this.childBtnClicked.next();
  }
}


//childComponent1
export class ChildComponent1 {
  @Output() btnClicked = new EventEmitter();


  emitAction(): void {
    this.btnClicked.emit(); // you can pass value to emit() method
  }
}

//childComponent2
export class ChildComponent2 implements OnInit, OnDestroy {
  @Input() clickBtnSubject: Subject;

  ngOnInit(): void {
    this.clickBtnSubject
      .pipe(takeUntil(this.destroy$))  // dont forget to unsubscribe, can cause memory leaks
      .subscribe(() => this.doSomething());
  }

  doSomething(): void {
    // your logic here
  }

  ngOnDestroy(): void {
    this.destroy$.next();
  }
}

答案 2 :(得分:0)

在您的general.component.html上:

<app-child1 (clicked)="app1Clicked($event)"></app-child1>

<app-child2 #child2></app-child2>

在您的general.component.ts上:

@ViewChild('child2', {static: true}) child2: Child2Component;

app1Clicked($event) {
   this.child2.doSomething()
}

在child1.components.ts上:

@Output() clicked = new EventEmitter<any>();

onClick() {
 this.clicked.emit();
}

最后在child2.component.ts上:

doSomething() {
 alert('ok');
}