[英]Share a method between two child components (Angular)
There is such structure of components:有这样的组件结构:
Desired Behavior期望的行为
child1_component
- is a header. child1_component
- 是一个标题。
child2_component
- is a body. child2_component
- 是一个身体。
There is a button inside child1_component
. child1_component
里面有一个按钮。
Clicking on that button I want to invoke a method inside child2_component
.单击该按钮,我想调用child2_component
一个方法。
Question题
What is the best way to implement this?实现这一点的最佳方法是什么?
One way to approach this would be to use a service with rxjs subjects and observables.解决这个问题的一种方法是使用带有 rxjs 主题和可观察对象的服务。
When the user clicks on the button in child1_component then it calls a method that in turn calls a method inside the shared service.当用户单击 child1_component 中的按钮时,它会调用一个方法,该方法又调用共享服务中的一个方法。
When the method in the service is called it can emit a value as an observable via a subject.当服务中的方法被调用时,它可以通过主题发出一个值作为可观察对象。
child2_component then subscribes to the observable within the shared service and can operate some logic based on when it receives data from the service. child2_component 然后订阅共享服务中的 observable 并可以根据它何时从服务接收数据来操作一些逻辑。
More on services here: https://angular.io/tutorial/toh-pt4更多关于这里的服务: https : //angular.io/tutorial/toh-pt4
Great tutorial on subjects and rxjs: https://blog.angulartraining.com/rxjs-subjects-a-tutorial-4dcce0e9637f关于主题和 rxjs 的精彩教程: https ://blog.angulartraining.com/rxjs-subjects-a-tutorial-4dcce0e9637f
There are 2 ways to do it:有两种方法可以做到:
1.Service: 1.服务:
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. Using Parent Component 2. 使用父组件
<child-component1 (btnClicked)="childComponentBtnClick()"></child-component1> <child-component2 [clickBtnSubject]="childBtnClicked"></child-component1>
Ts logic: 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();
}
}
On your general.component.html :在您的 general.component.html 上:
<app-child1 (clicked)="app1Clicked($event)"></app-child1>
<app-child2 #child2></app-child2>
On your general.component.ts:在您的 general.component.ts 上:
@ViewChild('child2', {static: true}) child2: Child2Component;
app1Clicked($event) {
this.child2.doSomething()
}
On the child1.components.ts:在 child1.components.ts 上:
@Output() clicked = new EventEmitter<any>();
onClick() {
this.clicked.emit();
}
Finally on the child2.component.ts:最后在 child2.component.ts 上:
doSomething() {
alert('ok');
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.