Angular 8-从两个不同组件订阅一个服务
我有一个角度服务和两个不同的不相关组件使用此服务: 服务代码:Angular 8-从两个不同组件订阅一个服务,angular,service,components,observable,subject,Angular,Service,Components,Observable,Subject,我有一个角度服务和两个不同的不相关组件使用此服务: 服务代码: const url = 'ws://localhost:8080 @Injectable({ provideIn: 'root', }) export class MyService{ public subject: Subject<Status>; constructor(wsService: WebSocketService){ this.subject = <Subject<
const url = 'ws://localhost:8080
@Injectable({
provideIn: 'root',
})
export class MyService{
public subject: Subject<Status>;
constructor(wsService: WebSocketService){
this.subject = <Subject<Status>>wsService.connect(url).map(
(response: MessageEvent): Status => {
let data = JSON.parse(response.data);
return data;
}
);
}
getObs(){
return this.subject.asObservable();
}
sendMsg(msg){
this.subject.next(msg);
}
}
构成部分2:
@Component
.. some irrelevant code ..
constructor(private service: MyService){
this.service.getObs().subscribe( data =>
console.log('comp2');
);
console.log('comp2 - after subscribe');
}
.. some irrelevant code ..
我在控制台中获得以下输出:
comp1
comp1-订阅后
comp2-订阅后
我认为我应该得到的输出:
comp1
comp1-订阅后
comp2
comp2-订阅后
有人能解释问题出在哪里吗
注意:我将我的服务添加到模块提供程序中,得到了相同的结果
谢谢
以下是webSocketService的代码:您可以使用行为主题而不是普通主题
您可以使用行为主语而不是普通主语
你应该控制自己的主题,而不是依赖
WebSocketService.connect
并假设你将获得所需的行为
从您发布的WebSocketService
源代码的链接中,我们可以看到它是一个简单的主题。您想要的功能—在订阅时发出值(如果存在值)—由ReplaySubject
提供
您应该声明一个本地ReplaySubject
,这是您的组件将订阅的。然后您将订阅您的WebSocketService
。来自WebSocketService
的任何响应都将映射到一个状态,然后发送到您的本地主题
consturl='ws://localhost:8080
@注射的({
provideIn:'根',
})
导出类MyService{
//声明在订阅时发出最后一个值的本地ReplaySubject
私有主题:主题=新的ReplaySubject(1);
构造函数(wsService:WebSocketService){
//订阅web套接字服务。
//订阅构造函数是相当糟糕的做法,
//虽然你可以在单例服务中侥幸逃脱
wsService.connect(url.pipe)(
//将响应映射到状态
映射((响应:MessageEvent):状态=>{
让data=JSON.parse(response.data);
返回数据;
})
).订阅((状态:status)=>{
//将状态发送给所有订阅者
本.主题.下一个(状态);
});
}
getObs():可观察{
返回此.subject.asObservable();
}
sendMsg(msg):无效{
this.subject.next(msg);
}
}
你应该控制自己的主题,而不是依靠WebSocketService.connect
并假设你将获得所需的行为
从您发布的WebSocketService
源代码的链接中,我们可以看到它是一个简单的主题。您想要的功能—在订阅时发出值(如果存在值)—由ReplaySubject
提供
您应该声明一个本地ReplaySubject
,这是您的组件将订阅的。然后您将订阅您的WebSocketService
。来自WebSocketService
的任何响应都将映射到一个状态,然后发送到您的本地主题
consturl='ws://localhost:8080
@注射的({
provideIn:'根',
})
导出类MyService{
//声明在订阅时发出最后一个值的本地ReplaySubject
私有主题:主题=新的ReplaySubject(1);
构造函数(wsService:WebSocketService){
//订阅web套接字服务。
//订阅构造函数是相当糟糕的做法,
//虽然你可以在单例服务中侥幸逃脱
wsService.connect(url.pipe)(
//将响应映射到状态
映射((响应:MessageEvent):状态=>{
让data=JSON.parse(response.data);
返回数据;
})
).订阅((状态:status)=>{
//将状态发送给所有订阅者
本.主题.下一个(状态);
});
}
getObs():可观察{
返回此.subject.asObservable();
}
sendMsg(msg):无效{
this.subject.next(msg);
}
}
wsService.connect(url)return是什么数据类型?WebSocketService
是您创建的吗?MyService没有任何明显的重播行为,组件2是否在触发组件1输出的消息后开始订阅?下面是webSocketService的代码:wsService.connect(url)
返回什么数据类型?并且webSocketService
是您创建的吗?MyService没有任何明显的重播行为,组件2是否在触发组件1输出的消息后开始订阅?下面是webSocketService的代码:我们不知道正在使用什么类型的主题-它只是被转换到一个主题
-这并不意味着它实际上是一个正常的主题
。我们需要更多关于代码的信息。有关主题的详细信息。这肯定不是一个行为主体。您可以使用下面的行为主题私有类别:BehaviorSubject=新的BehaviorSubject({})`我很清楚不同类型的主题。OP显然需要一个ReplaySubject
,因为没有初始状态。但是我们不知道wsService.connect(url)返回什么,所以任何答案都只是猜测。我们不知道正在使用什么类型的主题-它只是被转换到一个主题
-这并不意味着它实际上是一个正常的主题
。我们需要更多关于代码的信息。有关主题的详细信息。这肯定不是一个行为主体。您可以使用下面的行为主题私有类别:BehaviorSubject=新的BehaviorSubject({})`我很清楚不同类型的主题。OP显然需要一个ReplaySubject
,因为没有初始状态。但是我们不知道wsService.connect(url)返回什么,所以有什么答案吗
@Component
.. some irrelevant code ..
constructor(private service: MyService){
this.service.getObs().subscribe( data =>
console.log('comp2');
);
console.log('comp2 - after subscribe');
}
.. some irrelevant code ..