角4,如何传递提供程序实例 [英] angular 4, how to pass on provider instance

查看:83
本文介绍了角4,如何传递提供程序实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Mqtt服务,可以从中获取一些实时数据(几何形状和温度).
Mqtt服务:

I have a Mqtt-Service, where i get some live data from (geometry and temperature).
Mqtt-Service:

        import { Injectable } from '@angular/core';
        import {Paho} from '../../../../Own_paho_sript/geomqttws31';
        import {Subject} from 'rxjs/Subject';


        @Injectable()
        export class MqttdataproviderService {

          history = [
            {
              topic: '',
              timestamp: '',
              data: '',
              geometry: ''
            }
          ];

         mqttform = {

          addmqttadress: '',
          addmqttport: '',
          addmqttspatialfilter: '',
          addmqtttemporalfilter: '',
          addmqtttopicfilter: '',
          addmqttspatialrelation: '',
          addmqttusername: '',
          addmqttpassword: '',
          } ;

          private datamqtt = new Subject<any>();
          msg$ = this.datamqtt.asObservable();
          public msg = [];

         public constructor(private getformvaules: FormToClientService) {

         this.getformvaules.componentMethodCalled$.subscribe(
         () => {
         this.mqttform = this.getformvaules.addmqtt;
         this.methodToGetMyGeoData();
         });

         //to get live data and push the data in the history.
         this.methodToGetMyGeoData();
         }

          methodToGetMyGeoData() {
           // Methodes to subscrib and, connect to the paho 
            client

          this.client.onMessageArrived = (message: Paho.MQTT.Message) => {
              this.onMessage(message);
              this.history.push({
                'topic': message.destinationName,
                'timestamp': message.timestamp,
                'payloadstring': message.payloadString,
                'geometry': message.geometry
              });

          public onMessage(msg$: string) {
            this.geomsg.push(geomsg$);
            this.datageomqtt.next();

          }
          }

FormToClientService:

import { Injectable } from '@angular/core';
import {Subject} from 'rxjs/Subject';

@Injectable()
export class FormToClientService {


  addmqtt = {

              addmqttadress: '',
              addmqttport: '',
              addmqttspatialfilter: '',
              addmqtttemporalfilter: '',
              addmqtttopicfilter: '',
              addmqttspatialrelation: '',
              addmqttusername: '',
              addmqttpassword: '',
              } ;
  };


  //Observable string sources
  private componentMethodCallSource = new Subject<any>();

  // Observable string streams
  componentMethodCalled$ = this.componentMethodCallSource.asObservable();

  // Service message commands
  callComponentMethod() {
    this.componentMethodCallSource.next();
  }

  setMqtt (adress: string, port: any, spatial: string, temporal: any, topic: string, username: string, relation: string) {
    this.addmqtt.addmqttadress = adress;
    this.addmqtt.addmqttport = port;
    this.addmqtt.addmqttspatialfilter = spatial;
    this.addmqtt.addmqtttemporalfilter = temporal;
    this.addmqtt.addmqttspatialrelation = relation;
    this.addmqtt.addmqtttopicfilter = topic;
    this.addmqtt.addmqttusername = username;
    console.log('set');
  }


我通过Observables在4个不同的组件中订阅了历史记录数组.
1.在地图中,2.在数据表中,3.在量规中,4.在折线图中. 它们都是一样的:


I subscribed to the history array via Observables in 4 different components.
1. In a map, 2. in a datatable, 3. in a gauge, 4. in a linechart. They are all quite the same:

import {MqttdataproviderService} from '../../protocols/mqtt/mqttdataprovider.service';

@Component({
  selector: 'app-datatable',
  templateUrl: './datatable.component.html',
  styleUrls: ['./datatable.component.css'],
})
export class DatatableComponent  {
  rows = [];
  columns = [
    { prop: 'topic' },
    { name: 'payloadstring' },
    { name: 'geometry' },
    { name: 'timestamp' }
  ];
  constructor(private mqttprovider: MqttdataproviderService) {
      this.mqttprovider.msg$.subscribe(() => {
      this.rows = this.mqttprovider.history;
      this.rows = [...this.rows];
    });
}


我在单机全局声明了我的app.module中的MqttdataproviderService,并且一切正常!

但是现在我想创建MqttdataproviderService的多个实例或动态实例.我有几个主题要订阅,并且同时在地图组件或数据列表中显示来自不同主题的几何数据.
对于每个组件(地图,数据表,线图等),都有一个自己的窗口.

我如何传递每个创建的MqttdataproviderService的实例?


I declared the MqttdataproviderService in my app.module globally as a singleton and everyrhing works fine!

But now i want to create several instances or dynamical instances of the MqttdataproviderService. I have several topics i want to subscribe to and show the geometry data from the different topics at the same time in the map-component or in the datable.
For every component (map, datatable, linechart, ...) exists an own window.

How could i pass the instance of every created MqttdataproviderService?

推荐答案

Angular提供程序在定义的注入器中具有单个实例.考虑到单例在这里是不需要的,因此不应将其作为在注入时实例化的类提供程序(默认类型).

Angular providers have single instances in injectors they were defined. Considering that singleton is unwanted here, it shouldn't be class provider (default type) that is instantiated on injection.

如果MqttdataproviderService类没有可注入的依赖项,则不一定必须是提供程序.可以将其定义为价值提供者,主要是出于可测试性和可扩展性的原因:

If MqttdataproviderService class has no injectable dependencies, it doesn't necessarily have to be a provider. It can be defined as value provider, primarily for testability and extensibility reasons:

{ provide: MqttdataproviderService, useValue: MqttdataproviderService }

如果具有依赖项,则应在实例化时手动提供它们:

If it has dependencies, they should be provided manually on instantiation:

mqttprovider: MqttdataproviderService;

constructor(
  @Inject(MqttdataproviderService) private _MqttdataproviderService: typeof MqttdataproviderService,
  formToClientService: FormToClientService
) {
  this.mqttprovider = new this._MqttdataproviderService(formToClientService);
}

如果已知MqttdataproviderService类具有可注入的依赖项,则可以使用工厂提供程序代替:

If it is known that MqttdataproviderService class has injectable dependencies, factory provider can be used instead:

export function mqttdataproviderServiceFactory (formToClientService: FormToClientService) 
  return () => return new MqttdataproviderService(formToClientService);
}

...
{
  provide: mqttdataproviderServiceFactory,
  useFactory: mqttdataproviderServiceFactory,
  deps: [FormToClientService]
 }
...

然后可以注入用于实例化MqttdataproviderService的工厂函数:

Then factory function that is used to instantiate MqttdataproviderService can be injected:

mqttprovider: MqttdataproviderService;

constructor(@Inject(mqttdataproviderServiceFactory) public mqttdataproviderServiceFactory: () => MqttdataproviderService) {
  this.mqttprovider = mqttdataproviderServiceFactory();
}

在两种情况下,FormToClientService都是单例.如果不希望这样做,则应采用与MqttdataproviderService相同的方式进行处理.

In both cases FormToClientService will be a singleton. If this is undesirable, it should be handled in same way as MqttdataproviderService.

这篇关于角4,如何传递提供程序实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆