首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Angular5可观测数据不起作用

Angular5可观测数据不起作用
EN

Stack Overflow用户
提问于 2018-02-08 00:18:15
回答 1查看 68关注 0票数 0

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

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

我已经读到,使用另一个服务来处理这个问题是一个很好的实践,所以我已经为此创建了#dataService,这就是我处理可观察性的地方。

所以流程是:

headerComponent -> (触发器) #websocketService -> (搜索查询到)node.js-服务器-> (结果返回) #websocketService -> (set var in) #dataService -> (触发方法) #graphcomponent (包含来自#dataService的新数据)

所有操作都很好,除了我无法在#graphComponent中得到触发的方法之外。

dataService

代码语言:javascript
复制
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() { }
}

graphComponent

代码语言:javascript
复制
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')
}       
}

websocketService

代码语言:javascript
复制
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()

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-02-08 01:55:43

问题是你把一个可观察的分配给了一个可观察的。

数据服务中的graphData是可观察的,在组件中,您将视图模型属性graphData (它也是可观察的)设置为该服务返回的可观察对象。

相反,您需要将viewmodel值类型设置为websocket将返回的内容,比如stringobject,或者使用any

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

数据服务保持不变,但为了演示,我将套接字服务更改为点击web上的回显服务:

代码语言:javascript
复制
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);
    };
  }
}

我只是利用了在这个示例组件中由角CLI创建的app.component.ts来获得服务的值:

代码语言:javascript
复制
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运行示例代码,然后您将看到从服务回显的值。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48675478

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档