【问题标题】:Angular5 Observables are not workingAngular5 Observables 不工作
【发布时间】:2018-07-18 10:22:26
【问题描述】:

#headerComponent 中是我搜索的输入字段。当用户执行搜索时,搜索查询由#websocketsService 发送到节点服务器并返回 JSON 结果。

这个结果应该触发#graphComponent的方法。

我读到有另一个服务来处理这个是一个好习惯,所以我为此创建了#dataService,这是我处理可观察对象的地方。

所以流程是:

headerComponent -> (triggers) #websocketService -> (search query to) node.js-Server -> (result back to) #websocketService -> (set var in) #dataService -> (触发方法) #graphcomponent(来自#dataService 的新数据)

一切正常,除了我无法触发#graphComponent 中的方法。

数据服务

import { Injectable, EventEmitter, Output } from '@angular/core';
import { Subject } from 'rxjs/Subject';
import { Observable } from 'rxjs/Observable';

/**
 * This Service is for keep, simple and small Data sharing
 * to communicate between components
 */
@Injectable()
export class DataService {

private subject = new Subject<any>();

public setGraphData(data) {
   console.log('setGraphData:' + data);
   this.subject.next({text: data});
}

public getGraphData(): Observable<any> {
   console.log('get graphDataSubject');
   return this.subject.asObservable();
}

constructor() { }
}

图形组件

import { Component, OnInit} from '@angular/core';
import { Subject } from 'rxjs/Subject';
import { Subscription } from 'rxjs/Subscription';
import { DataService } from '../../../services/data/data.service';
import { Observable } from 'rxjs/Observable';

@Component({
  selector: 'graph',
  templateUrl: './graph.component.html',
  styleUrls: ['./graph.component.scss'],
  providers: [DataService]
})
export class GraphComponent implements OnInit{ 

  graphData: Observable<any>;
  subscription: Subscription;

  constructor( private _dataService: DataService ) { }

  ngOnInit() {    
    this._dataService.getGraphData().subscribe(graphData => {
      console.log('PLEASE TRIGGER ME WHEN graphData IS UPDATED');
    });
  } 

// PLEASE TRIGGER THIS FUNCTION WHEN NEW graphData IS SET
triggerMe() {
    console.log('WORKS')
}       
}

websocket服务

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
import { DataService } from '../data/data.service';

@Injectable()
export class WebsocketsService {
  private _search: string;
  private url: string;
  public wsConnection: WebSocket;

  constructor(private _dataService: DataService) {
    this.url = 'ws://localhost:1337';
  }

 /*
  * creates connection, sends query and maps ws-handler
  */
  sendQuery(search: string) {

    this._search = search;
    console.log('Perform search for: ' + this._search);
    this.wsConnection = new WebSocket(this.url);
    this.wsConnection.onopen = () => this.wsConnection.send(JSON.stringify({ data: this._search }));
    this.wsConnection.onerror = event => console.log('A Error has occured!');
    this.wsConnection.onclose = event => console.log('Connection closed');
    this.wsConnection.onmessage = (event) => {
      // SEND NEW DATA TO OBSERVABLE      
      this._dataService.sendGraphData(event.data);
    };
  }
}

我只是无法让它运行,当在#dataService 中设置新的graphData 时,会触发#graphComponent 中的triggerMe()

【问题讨论】:

    标签: angular components observable


    【解决方案1】:

    问题是你将一个 Observable 分配给一个 Observable。

    您的数据服务中的graphData 是一个Observable,而在您的组件中,您将viewmodel 属性graphData(也是一个Observable)设置为服务返回的Observerable。

    相反,您需要将 viewmodel 值类型设置为与 websocket 将返回的值相同,例如 stringobject,或者平底船并使用 any

    我已经更改了一些名称,并为此创建了一个示例项目。这是源代码的链接:https://1drv.ms/u/s!Aun50jHsxPB0gcd4emGcDqViLGbySw

    数据服务不变,但是我把socket服务改成在web上打一个echo服务来演示:

    import { Injectable } from '@angular/core';
    import { Subject } from 'rxjs/Subject';
    import { DataService } from './data.service';
    
    @Injectable()
    export class SocketService {
      public wsConnection: WebSocket;
    
      url: string;
    
      constructor(private _dataService: DataService) {
        this.url = 'ws://echo.websocket.org/';
      }
    
     /*
      * creates connection, sends query and maps ws-handler
      */
      sendQuery(): void {
    
        this.wsConnection = new WebSocket(this.url);
        this.wsConnection.onopen = () => this.wsConnection.send('Test Message');
        this.wsConnection.onerror = event => console.log('A Error has occured!');
        this.wsConnection.onclose = event => console.log('Connection closed');
        this.wsConnection.onmessage = (event) => {
          this._dataService.setGraphData(event.data);
        };
      }
    }
    

    我只是在这个示例组件中利用 Angular CLI 创建的 app.component.ts 从服务中获取值:

    import { Component, OnInit, OnDestroy} from '@angular/core';
    import { Subject } from 'rxjs/Subject';
    import { Subscription } from 'rxjs/Subscription';
    import { DataService } from './data.service';
    import { SocketService } from './socket.service';
    
    @Component({
      selector: 'app-root',
      template: `
        Graph Data: {{ data }}
      `,
    })
    export class AppComponent implements OnInit, OnDestroy {
    
      data: any; // <-- not an Observable
      subscription: Subscription;
    
      constructor (
        private dataService: DataService,
        private socketService: SocketService,
      ) {}
    
      ngOnInit() {
        // Get the data from the socket service
        this.socketService.sendQuery();
    
        this.subscription = this.dataService.getGraphData().subscribe(graphData => {
          // set the value in the viewmodel with the data from the service
          this.data = graphData.text;
        });
      }
    
      ngOnDestroy(): void {
        this.subscription.unsubscribe();
      }
    
    }
    

    首先,安装依赖项,然后使用:ng serve 运行示例代码,您将看到从服务回显的值。

    【讨论】:

    • 嗨,谢谢您的回答.. 但它不起作用:/ .. 我使用 console.log() 跟踪数据流,一切看起来都很好.. 除了订阅者,他们没有被触发/通知..就像你的例子一样,在this.subscription = this.dataService.getGraphData().subscribe(....)中我也做了console.log('success'),但什么也没发生..
    • 它在我运行代码时工作。我将制作另一个接受表单输入的示例,然后 ping websocket 并在状态更改时将回显值绑定回模板。
    • @Mka24 查看更新后的项目:1drv.ms/u/s!Aun50jHsxPB0gcd56JPGHlFajqkiJg 的示例,它接受来自表单的输入,将其传递给 websocket,然后将值设置为 Observable。
    • 嗨,谢谢 :) .. 当我将它适应我的项目时,它并没有立即起作用,但你的回答是 100% 正确的。我现在确实让它工作了。非常感谢:)
    • 不客气,很高兴你能够让它工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多