Angular:如何从服务内的事件中获取数据到我的组件?

Posted

技术标签:

【中文标题】Angular:如何从服务内的事件中获取数据到我的组件?【英文标题】:Angular: How do I get data from an event inside a service to my component? 【发布时间】:2021-11-23 00:02:16 【问题描述】:

我目前正在编写一个 Angular 项目,它打开与 NodeJS 服务器的 websocket 连接。这是服务:

export class WebsocketService 

  socket : any;

  constructor()  

  setupSocketConnection()
    this.socket = io(environment.SOCKET_ENDPOINT);
    this.socket.emit('message', 'The client wants to intruduce itself to the server');

    this.socket.on('broadcast', (data: string) => 
      console.log(data);
    );
  

  disconnect() 
    if (this.socket) 
      this.socket.disconnect();
    
  

这是我的组件:

export class AppComponent 
  title = '-'; 

  constructor(private websocket : WebsocketService)  

  ngOnInit()
    this.websocket.setupSocketConnection();
  

  ngOnDestroy() 
    this.websocket.disconnect();
  

我的问题是:如何将“数据”从广播事件侦听器传递到组件中以在那里显示?另一项服务将是一个解决方案,但我认为这不是一个好的解决方案。我也可以将监听器放到一个函数中,然后从组件中调用它,但这不会违反服务的封装概念吗?

谢谢

【问题讨论】:

【参考方案1】:

您可以按照以下步骤使用 BehaviorSubject:

想象一下发送 JSON 对象包含一个“类型”字段:确保对发送的数据进行字符串化

1- 服务器端:

JSON.stringify(type: "message", value: "whatever")

2- 现在是客户端

export class WebsocketService 

  // Put the right data type here
  message = new BehaviorSubject<string>('');
  connection = new BehaviorSubject<string>('');

  socket : any;

  constructor()  

  setupSocketConnection()
    this.socket = io(environment.SOCKET_ENDPOINT);
    this.socket.emit('message', 'The client wants to intruduce itself to the server');

    this.socket.on('broadcast', (data: string) => 
      const jsonObject = JSON.parse(data);
      switch (jsonObject.type) 
        case "message":
          this.message.next(jsonObject.value);
          break;

        case "connection":
          this.connection.next(jsonObject.value);
          break;

        default:
          throw new Error('Unknown message type' + jsonObject.type)
          break;
      
    );
  

  disconnect() 
    if (this.socket) 
      this.socket.disconnect();
    
  

另一方面,只需订阅您的数据 behaviorSubject 发出的值。

export class AppComponent implements OnInit, OnDestroy 
  title = '-'; 

  subscriptions: Subscription[] = [];
  constructor(private websocket : WebsocketService)  

  ngOnInit()
    this.websocket.setupSocketConnection();
    this.websocket.message.subscribe(value => 
        // Do your stuff here.
        console.log(value);
    )

    this.websocket.connection.subscribe(value => 
        // Do your stuff here.
        console.log(value);
    )
  

  ngOnDestroy() 
    this.websocket.disconnect();
    this.subscriptions.forEach(s => s.unsubscribe());
    this.subscription = [];
  

【讨论】:

感谢您的帮助!我真的被困在这里,我找不到有关此问题的任何资源。我现在将实施这一点。可悲的是我不能投票给你,因为我的声誉为零,否则我会 没问题,我是来帮忙的,不是抓点;). 嘿,我有一个后续问题。我决定使用一个 websocket 来处理登录和其他所有事情。现在我想知道如何将 BehaviorSubject 更改为只为组件提供所需的数据而不是所有内容? 为什么不通过服务器发送JSON,然后在前面解析。确保添加“类型”字段,然后根据“类型”值,使用不同的 BehaviorSubject 并订阅它以实现您的目标?

以上是关于Angular:如何从服务内的事件中获取数据到我的组件?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 ngOnInit Angular 中的服务获取数据

如何将 json 加载到我的 angular.js ng-model 中?

如何正确使用 Angular 中的 Observable 将数组数据从父级发送到子级?

如何将从服务接收到的 json 数据传递到 Angular 4 的角材料组件中的数组

如何将 node.js 服务器变量传递到我的 angular/html 视图中?

循环内的承诺:TypeScript + Angular + IndexedDB