Angular 您能否从角度服务连续生成正弦波数据并将其注入组件?

Angular 您能否从角度服务连续生成正弦波数据并将其注入组件?,angular,typescript,Angular,Typescript,我有一个组件,它有一个注入的服务来检索静态模拟数据。我想添加以可变频率生成数据的功能,并在生成组件时将新的(附加的时间序列)数据发送到组件 我一辈子都想不出如何做到这一点 我可以肯定的是,组件的数据对象必须是不可变的 如果方向正确,我们将不胜感激。我想也许有一次我需要一个服务人员,但这对于一个模型来说似乎有点过分了。最终,该服务将实际使用流通过internet连接到数据源,但在那天之前,我希望能够假装有一个数据流从服务到组件,用于UI开发/原型设计 plotter.component.ts: i

我有一个组件,它有一个注入的服务来检索静态模拟数据。我想添加以可变频率生成数据的功能,并在生成组件时将新的(附加的时间序列)数据发送到组件

我一辈子都想不出如何做到这一点

我可以肯定的是,组件的数据对象必须是不可变的

如果方向正确,我们将不胜感激。我想也许有一次我需要一个服务人员,但这对于一个模型来说似乎有点过分了。最终,该服务将实际使用流通过internet连接到数据源,但在那天之前,我希望能够假装有一个数据流从服务到组件,用于UI开发/原型设计

plotter.component.ts:

import { Component, OnInit } from '@angular/core';

import { MockDataService } from '../../services/mock-data/mock-data.service';

@Component({
  selector: 'app-plotter',
  templateUrl: './plotter.component.html',
  styleUrls: ['./plotter.component.css']
})
export class PlotterComponent implements OnInit {

  single: any[];
  multi: any[];

  // rt needs to be an immutable object array
  // rt needs to be updated with data from MockDataService
  rt: any[];

  view: any[] = [700, 400];

  // options
  showXAxis = true;
  showYAxis = true;
  gradient = false;
  showLegend = true;
  showXAxisLabel = true;
  xAxisLabel = 'Country';
  showYAxisLabel = true;
  yAxisLabel = 'Population';

  colorScheme = {
    domain: ['#5AA454', '#A10A28', '#C7B42C', '#AAAAAA']
  };

  // line, area
  autoScale = true;

  constructor(private mockDataService: MockDataService) {
    // Object.assign(this, { single, multi });
    this.single = mockDataService.getSingle();
    this.multi = mockDataService.getMulti();
  }

  ngOnInit() {

  }

  onSelect(event) {
    console.log(event);
  }

}
import { Component, OnInit } from '@angular/core';
import { MockDataService } from '../../services/mock-data/mock-data.service';
import { timer, Subscription } from 'rxjs';

@Component({
  selector: 'app-plotter',
  templateUrl: './plotter.component.html',
  styleUrls: ['./plotter.component.css']
})
export class PlotterComponent implements OnInit {
  /*
   timer takes a second argument, how often to emit subsequent values
   in this case it will call the method for the first time after 1 second and
   subsequent calls follow every 10 seconds after
  */
  const source = timer(1000, 10000);
  let subscription: Subscription;

  single: any[];
  multi: any[];

  pAmplitude: number = 0;
  pFrequency: number = 0;

  // rt needs to be an immutable object array
  // rt needs to be updated with data from MockDataService
  rt: any[];

  view: any[] = [700, 400];

  // options
  showXAxis = true;
  showYAxis = true;
  gradient = false;
  showLegend = true;
  showXAxisLabel = true;
  xAxisLabel = 'Country';
  showYAxisLabel = true;
  yAxisLabel = 'Population';

  colorScheme = {
    domain: ['#5AA454', '#A10A28', '#C7B42C', '#AAAAAA']
  };

  // line, area
  autoScale = true;

  constructor(private mockDataService: MockDataService) { }

  ngOnInit() {
      this.mockDataService.getSingle().subscribe( data => {
          this.single = data;
      });

      this.mockDataService.getMulti().subscribe( data => {
          this.multi = data;
      });

      this.startPolling();
  }

  ngOnDestroy(): {
      this.subscription.unsubscribe();
  }

  startPolling(): void {
      this.subscription = source.subscribe(
          () => {
                  // increase the value of both variables then
                  // call the method in the service and hand in the variables
                  this.pFrequency += 12;
                  this.pAmplitude += 24;
                  this.mockDataService.sineWave(this.pAmplitude, this.pFrequency); 
                }
      );
  }

  onSelect(event) {
    console.log(event);
  }

}
模拟数据.service.ts

import { Injectable } from '@angular/core';
import { single, multi } from '../../mock-data/plot-data';

@Injectable({
  providedIn: 'root'
})
export class MockDataService {

  constructor() { }

  getSingle() {
    return single;
  }

  getMulti() {
    return multi;
  }

  // Generate sine wave data here
  sineWave(pAmplitude, pFrequency) {

  }

}
import { Injectable } from '@angular/core';
import { single, multi } from '../../mock-data/plot-data';
import { Observable, BehaviorSubject, } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class MockDataService {

  private single: BehaviorSubject<any[]> = new BehaviorSubject([]);
  private multi: BehaviorSubject<any[]> = new BehaviorSubject([]);

  constructor() { 
  }

  getSingle(): Observable<any[]> {
    return single.asObservable();
  }

  setSingle(data: any[]): void {
      this.single.next(data);
  }

  getMulti(): Observable<any[]> {
    return multi.asObservable();
  }

  setMulti(data: any[]): void {
      this.multi.next(data);
  }

  // Generate sine wave data here
  sineWave(pAmplitude, pFrequency) {
      console.log('set new pAmplitude: ', pAmplitude);
      console.log('set new pFrequency: ', pFrequency);
  }

}

最好的方法是将数组放在Subject或BehaviorSubject中。然后将其作为可观察对象返回并订阅。现在,只要您在服务中使用setter更改其中一个数组的值,组件的数组副本就会自动更新

plotter.component.ts:

import { Component, OnInit } from '@angular/core';

import { MockDataService } from '../../services/mock-data/mock-data.service';

@Component({
  selector: 'app-plotter',
  templateUrl: './plotter.component.html',
  styleUrls: ['./plotter.component.css']
})
export class PlotterComponent implements OnInit {

  single: any[];
  multi: any[];

  // rt needs to be an immutable object array
  // rt needs to be updated with data from MockDataService
  rt: any[];

  view: any[] = [700, 400];

  // options
  showXAxis = true;
  showYAxis = true;
  gradient = false;
  showLegend = true;
  showXAxisLabel = true;
  xAxisLabel = 'Country';
  showYAxisLabel = true;
  yAxisLabel = 'Population';

  colorScheme = {
    domain: ['#5AA454', '#A10A28', '#C7B42C', '#AAAAAA']
  };

  // line, area
  autoScale = true;

  constructor(private mockDataService: MockDataService) {
    // Object.assign(this, { single, multi });
    this.single = mockDataService.getSingle();
    this.multi = mockDataService.getMulti();
  }

  ngOnInit() {

  }

  onSelect(event) {
    console.log(event);
  }

}
import { Component, OnInit } from '@angular/core';
import { MockDataService } from '../../services/mock-data/mock-data.service';
import { timer, Subscription } from 'rxjs';

@Component({
  selector: 'app-plotter',
  templateUrl: './plotter.component.html',
  styleUrls: ['./plotter.component.css']
})
export class PlotterComponent implements OnInit {
  /*
   timer takes a second argument, how often to emit subsequent values
   in this case it will call the method for the first time after 1 second and
   subsequent calls follow every 10 seconds after
  */
  const source = timer(1000, 10000);
  let subscription: Subscription;

  single: any[];
  multi: any[];

  pAmplitude: number = 0;
  pFrequency: number = 0;

  // rt needs to be an immutable object array
  // rt needs to be updated with data from MockDataService
  rt: any[];

  view: any[] = [700, 400];

  // options
  showXAxis = true;
  showYAxis = true;
  gradient = false;
  showLegend = true;
  showXAxisLabel = true;
  xAxisLabel = 'Country';
  showYAxisLabel = true;
  yAxisLabel = 'Population';

  colorScheme = {
    domain: ['#5AA454', '#A10A28', '#C7B42C', '#AAAAAA']
  };

  // line, area
  autoScale = true;

  constructor(private mockDataService: MockDataService) { }

  ngOnInit() {
      this.mockDataService.getSingle().subscribe( data => {
          this.single = data;
      });

      this.mockDataService.getMulti().subscribe( data => {
          this.multi = data;
      });

      this.startPolling();
  }

  ngOnDestroy(): {
      this.subscription.unsubscribe();
  }

  startPolling(): void {
      this.subscription = source.subscribe(
          () => {
                  // increase the value of both variables then
                  // call the method in the service and hand in the variables
                  this.pFrequency += 12;
                  this.pAmplitude += 24;
                  this.mockDataService.sineWave(this.pAmplitude, this.pFrequency); 
                }
      );
  }

  onSelect(event) {
    console.log(event);
  }

}
模拟数据.service.ts

import { Injectable } from '@angular/core';
import { single, multi } from '../../mock-data/plot-data';

@Injectable({
  providedIn: 'root'
})
export class MockDataService {

  constructor() { }

  getSingle() {
    return single;
  }

  getMulti() {
    return multi;
  }

  // Generate sine wave data here
  sineWave(pAmplitude, pFrequency) {

  }

}
import { Injectable } from '@angular/core';
import { single, multi } from '../../mock-data/plot-data';
import { Observable, BehaviorSubject, } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class MockDataService {

  private single: BehaviorSubject<any[]> = new BehaviorSubject([]);
  private multi: BehaviorSubject<any[]> = new BehaviorSubject([]);

  constructor() { 
  }

  getSingle(): Observable<any[]> {
    return single.asObservable();
  }

  setSingle(data: any[]): void {
      this.single.next(data);
  }

  getMulti(): Observable<any[]> {
    return multi.asObservable();
  }

  setMulti(data: any[]): void {
      this.multi.next(data);
  }

  // Generate sine wave data here
  sineWave(pAmplitude, pFrequency) {
      console.log('set new pAmplitude: ', pAmplitude);
      console.log('set new pFrequency: ', pFrequency);
  }

}
从'@angular/core'导入{Injectable};
从“../../mock data/plot data”导入{single,multi};
从“rxjs”导入{Observable,BehaviorSubject,};
@注射的({
providedIn:'根'
})
导出类MockDataService{
private single:BehaviorSubject=new BehaviorSubject([]);
private multi:BehaviorSubject=新的BehaviorSubject([]);
构造函数(){
}
getSingle():可观察{
返回single.asObservable();
}
设置单个(数据:任意[]):无效{
this.single.next(数据);
}
getMulti():可观察{
返回multi.asObservable();
}
setMulti(数据:任意[]):无效{
this.multi.next(数据);
}
//在这里生成正弦波数据
正弦波(pAmplitude、PFF频率){
log('set new pAmplitude:',pAmplitude);
console.log('设置新的PFFrequency:',PFFrequency);
}
}

如果此答案解决了您的问题或回答了您的问题,请不要忘记将其标记为解决方案。提前谢谢!当我在等待答复时,实际上我正走在这条路上。那么,我可以在某种循环中运行sinWave函数(我仍然对此感到困惑)并让它使用set函数将新点添加到数组中吗?经进一步考虑。。也许我需要在另一个与绘图仪通信的组件中生成正弦波,并在其中注入mock-data.service?给你。我更新了答案。请看一下我添加的
计时器。当前配置显示,它在1秒后启动并调用
sinWave()
。然后每10秒重复一次此调用,直到调用
ngondstroy()
。整个机制通过
this.startPolling()在
ngOnInit()
中启动——关于第二个问题:在服务中,您不必使用setter。您可以直接使用
multi.next()
single.next()希望这能有所帮助。PS:谁来设定值的问题只能由你自己来回答,因为我不知道你是从哪里得到这些值的。理论上,mockservice可以自己生成它们。或者负责这些值的另一个服务注入mockserie,并在生成值后立即设置这些值。一切可能。你必须找出什么最适合你的需要。我想你已经帮助我理解了我在这里想要实现的目标。我要试一试。谢谢你的帮助!