6

Sto creando un'applicazione di esempio per effettuare la connessione a un server Websocket in ionic 2 in dattiloscritto. link alla repoCome passare i parametri per la dipendenza durante l'iniezione di servizi nei servizi in Angular 2 (Ionic 2/Angular 2/Typescript)

La mia esigenza è quella di rendere il collegamento websocket durante l'applicazione si avvia

sto usando angular2-websocket per la creazione della connessione.

Riferimenti:

  1. http://blog.thoughtram.io/angular/2015/09/17/resolve-service-dependencies-in-angular-2.html

  2. http://blog.thoughtram.io/angular/2015/05/18/dependency-injection-in-angular-2.html

sto ottenendo un errore "non può risolvere tutti i parametri per '$ WebSocket' (? String, Array,) Assicurarsi che tutti i parametri siano decorati con Inject o abbiano annotazioni di tipo valide e che '$ WebSocket' sia decorato con Injectable. "

CODICE: app.ts

import {App, Platform} from 'ionic-framework/ionic'; 
import {TabsPage} from './pages/tabs/tabs'; 
import {ConnectionService} from './framework/connection/connection-service' 
import {$WebSocket} from 'angular2-websocket/angular2-websocket'; 
import {bootstrap} from 'angular2/platform/browser'; 

// https://angular.io/docs/ts/latest/api/core/Type-interface.html 
import {Type} from 'angular2/core'; 


@App({ 
    template: '<ion-nav [root]="rootPage"></ion-nav>', 
    config: {} 
}) 
export class MyApp { 
    rootPage: Type = TabsPage; 

    constructor(platform: Platform, private conn : ConnectionService) { 
    platform.ready().then(() => { 
     this.conn.connect(); 
    }); 
    } 
} 
bootstrap(MyApp, [$WebSocket, ConnectionService]); 

connection-service.ts

import {Injectable, Component, Inject} from 'angular2/core'; 
import {$WebSocket} from 'angular2-websocket/angular2-websocket'; 
import {bootstrap} from 'angular2/platform/browser'; 

@Injectable() 
export class ConnectionService { 

    private _status: number; 

    //private connection: $WebSocket; 

    constructor(private connection : $WebSocket = new $WebSocket("ws://echo.websocket.org")) { 

    console.log("Starting connection"); 

    //this.connection = new $WebSocket("ws://echo.websocket.org"); 

    this.connection.onClose(this.onCloseHandler); 
    this.connection.onError(this.onErrorHandler); 
    this.connection.onOpen(this.onOpenHandler); 
    this.connection.onMessage(this.onRecieveHandler, {}); 

} 
... 
public connect() { 
    this.connection.connect(true); 
} 
... 
} 
bootstrap(ConnectionService, [$WebSocket]); 

risposta

4

la soluzione al mio problema stava usando @App() (specifico per ionica) campo fornitore di Annotazione invece di usare bootstrap

bootstrap(ConnectionService, 
    [provide($WebSocket, useValue: new WebSocket("ws://echo.websocket.org")]); 

Eg.

@App({ 
    template: '<ion-nav [root]="rootPage"></ion-nav>', 
    config: {}, 
    providers : [ provide($WebSocket, { useValue: new $WebSocket("ws://echo.websocket.org") }), ConnectionService] 
}) 

campione di lavoro può essere trovato here

+0

'@App()' è un'annotazione specifica ionica? –

+1

@Gunter sì è specifica per Ionic. Può essere importata da 'ionic-framework/ionic'; – tymspy

+0

Ciò significa che non è necessario eseguire il bootstrap nelle app Ionic2 @tymSpy? –

2

Ovviamente il $WebSocket richiede un string, array e un altro parametro che rende $WebSocket non iniettabili, almeno non direttamente.

Come soluzione alternativa è possibile utilizzare

import {Injectable, Component, Inject, provide} from 'angular2/core'; 

bootstrap(ConnectionService, 
    [provide($WebSocket, { useValue: new $WebSocket("ws://echo.websocket.org") })]); 

Ci sono altre opzioni se la stringa letterale non è ciò che si vuole, come una fabbrica.

+0

@tymspy, grazie per il fissaggio! Uso solo Dart me stesso e spesso dimentico delle differenze di sintassi. –

0

Da quello che vedo, è necessario fornire $WebSocket per iniezione poiché l'istanziato dal proprio per il proprio servizio. Vorrei rimuoverlo dalla bootstrap e creare un'istanza nel costruttore invece di fornire da parametri del costruttore:

@Injectable() 
export class ConnectionService { 
    private _status: number; 
    private connection: $WebSocket; 

    constructor() { 
    this.connection = new $WebSocket("ws://echo.websocket.org"); 
    } 
} 

Detto questo, in generale, se si vuole sfruttare l'iniezione di dipendenza in angolare, è necessario lasciare Angular2 istanziare da stesso cose che si vogliono iniettare nel costruttore.

Nel tuo caso, Angular2 tenta di creare un'istanza del servizio $WebSocket. Penso che il suo costruttore accetta tre parametri e quando Angular2 tenta di risolvere questi parametri a livello di istanziazione. Non può risolvere l'ultimo. Potresti fornire i parametri del costruttore $WebService?

+0

url: string, protocolli?: Array , config ?: WebSocketConfig. Gli ultimi due sono opzionali. – tymspy

+1

Infatti, 'WebSocketConfig' è qualcosa che Angular2 non è in grado di risolvere. Se si desidera utilizzare '$ WebSocket' con l'iniezione delle dipendenze, è necessario impostare un fornitore per questo:' fornire (WebSocketConfig, useValue: new WebSocketConfig (...) 'ma penso che si avranno problemi con i parametri delle stringhe. –

+0

Grazie per il suggerimento. Ho utilizzato i fornitori di annotazioni dell'app decor invece di bootstrap con ($ WebSocket, useValue: new WebSocket ("ws: //echo.websocket.org") risolto il mio problema – tymspy