问题
I want to achieve this -
// component1
load(){
// code...
}
// component2
component1.load();
So, basically I just want to call function of different component from a component.
I have read through the internet that there are 3 ways to share data between components, In my app, I am using Service Sharing to share data between my components.
But how I can simply call a function from different component with service sharing approach ?
回答1:
You can use the following service based on observables. It's using messages as string, but you can make it more generic if you need to pass data between components. In my normal services, I usually pass a message that contains message type and message data for instance
Basically, one component compoennt broadcast a message, and the other one listen to messages
Try this
message-service.ts
import {Injectable} from '@angular/core';
import {Observable, Subject} from "rxjs";
@Injectable()
export class MessageService
{
//subject to trigger events
private mySubject: Subject<any> = new Subject<string>();
//observable to listen to events
public readonly messageReceived$: Observable<string> = this.mySubject.asObservable();
//
brodcast(message: string)
{
this.mySubject.next(message );
}
}
component1.ts
constructor(private service: MessageService){}
//...
this.service.broadcast('triggerLoadMethod'); //broadcast a message for service subscriber to receive
component2
constructor(private service: MessageService)
{
//subscribe to observableto receive messages
this.service.messageReceived$.subscribe( message =>
{
if(message == 'triggerLoadMethod') //if we are interested in the message, process it
{
this.load();
}
});
}
回答2:
You can use BehaviorSubject
. Here's how.
App Component Template:
App Component!
<hello></hello>
<sibling></sibling>
EventService
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
@Injectable()
export class EventService {
event: BehaviorSubject<any> = new BehaviorSubject<any>(null);
emitEvent(data) {
console.log('next Called with ', data);
this.event.next(data);
}
}
HelloComponent:
import { Component, Input } from '@angular/core';
import { EventService } from './event.service';
@Component({
selector: 'hello',
template: `<h1>Hello {{name}}!</h1>`,
styles: [`h1 { font-family: Lato; }`]
})
export class HelloComponent {
constructor(private eventService: EventService) {}
ngOnInit() {
this.eventService.event
.subscribe(data => {
console.log('data received', data);
this.someMethod(data);
});
}
someMethod(data) {
console.log('some method got called!', data);
}
}
Siblingcomponent:
import { Component, Input } from '@angular/core';
import { EventService } from './event.service';
@Component({
selector: 'sibling',
template: `<button (click)="onClick()">Call Hello Component's Method</button>`,
styles: [`h1 { font-family: Lato; }`]
})
export class SiblingComponent {
constructor(private eventService: EventService) {}
onClick() {
console.log('onClick Called');
this.eventService.emitEvent({ foo: 'bar' });
}
}
Here's a StackBlitz for your reference.
回答3:
I don't think you generally call the method directly. Its good to keep separation of concerns. The best way is to use observables to handle this.
Service:
import { Injectable } from '@angular/core'; import { Subject } from 'rxjs';
@Injectable({
providedIn: 'root',
})
export class EventService {
myEvent: Subject<void>;
constructor() {
this.myEvent = new Subject<void>();
}
getEvent() {
return this.myEvent.asObservable();
}
callEvent() {
this.myEvent.emit();
}
}
Component1:
constructor(private eventService: EventService);
ngOnInit() {
this.eventService.subscribe(event => this.load())
}
load() {
}
Component2
constructor(private eventService: EventService);
ngOnInit() {
this.eventService.callEvent();
}
This way component2 can publish the event anytime it wants. For that matter, any component can call the event anytime it wants. And Component1 can subscribe to the event. For that matter, any component can subscribe to the event. So the code is more extendable and more maintainable.
来源:https://stackoverflow.com/questions/52206293/angular-call-function-from-different-component-with-service-sharing