Los dispositivos angular 2 y Cordova están listos

SOURCE 6020 palabras angularcordova

Detalles del problema

tengo una aplicación Cordova incorporada en angular 2. He creado un plug - in personalizado que entra en el dispositivo para recuperar algunos datos y luego los devuelve a una página donde todo está bien.
Sin embargo, cuando esta página se ejecuta al inicio de la apertura de la aplicación, el evento de preparación del dispositivo no se ha activado, por lo que los datos están vacíos (como se esperaba) porque se inició antes de que el dispositivo estuviera listo.
¿Cómo puedo notificar a angular 2 que se ha producido un evento de preparación del dispositivo? Normalmente crearía un tema y me suscribiría a él.
Estoy pensando en hacer esto en el punto de entrada de la aplicación, y usar emit () para notificar el área en la aplicación:
document.addEventListener('deviceready', deviceReady());
¿Hay una mejor opción? Sé que lanzarás la aplicación en angular 1, pero funciona de manera diferente en V2.
Actualización - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Estoy de acuerdo con la respuesta n00dl3.
Pero lo uso para mi servicio:
declare var IPFinder, Windows, device;
@Injectable()
export class DeviceService {
  // contains the api's for each plugin used
  device: Observable<any>;

  constructor(private cordovaService: CordovaService) {
    this.deviceReadyEvent();
  }

  // when the device is ready
  deviceReadyEvent() {
    this.device = this.cordovaService.deviceReady.map(() => {
      console.log('DEVICE READY IN ANGULAR');

      // add plugins here
      let deviceAPI = {
        IPFinder: IPFinder,
        device: device
      };

      this.platformSpecific(deviceAPI);

      return deviceAPI;

    });
  }

  private platformSpecific(deviceAPI) {
    if (device.platform === 'windows') {
      deviceAPI['Windows'] = Windows;
    }
  }

}
Luego lo llamo usando el siguiente método (un servicio de dispositivo privado es necesario en el constructor: Servicio de dispositivo & Zona):
   this.deviceService.device.subscribe((device) => {

      device.IPFinder.getIP((ips) => {
        // zone required to update view
        this.zone.run(() => {
          this.setIPAddress(ips);
        });
      }, (error) => {
        console.log('error', error);
      });
    });

La solución más común

Puede crear un servicio para manejar eventos Cordova y mapear datos observables de ese Observable en otros servicios. (He proporcionado un servicio para mi caso personal a través de plug - ins...)
En este ejemplo, quiero usar cordova-plugin-device para obtener información de la Plataforma. Necesita la definición del tipo de instalación: @types/cordova-plugin-device.
Córdoba. Servicio. TS
@Injectable()
export class CordovaService {
    deviceReady: Observable<Event>;
    constructor() {
        this.deviceReady = Observable.fromEvent(document, "deviceready").publishReplay(1);
        (this.deviceReady as ConnectableObservable<Event>).connect();
    }
}
Usted necesita establecer publishReplay(1) y connect() para este evento en particular, ya que se activa una vez, y cualquier otro oyente se llama inmediatamente una vez que el dispositivo está listo:

The deviceready event behaves somewhat differently from others. Any event handler registered after the deviceready event fires has its callback function called immediately.


Instalación. Servicio. TS
@Injectable()
export class DeviceService{
    platform:Observable<any>;
    constructor(private cdv:CordovaService){
        this.platform = this.cdv.deviceReady.map(()=>device.platform);
    }

}
En componentes aleatorios:
this.deviceService.platform.subscribe(platform=>console.log(platform));
Si realiza una operación que requiere una retrollamada (esencialmente cualquier llamada de operación nativa Cordova), puede crear una observable usando Observable.create(). Ejemplo de API del sistema de archivos:
Sistema de archivos. Servicio. TS
@Injectable()
export class FileSystemService {
    constructor(private cdv: CordovaService, private zone: NgZone) { }
    read(file: FileEntry, mode: "text" | "arrayBuffer" | "binaryString" | "dataURL" = "text") {
        return this.cdv.deviceReady.switchMap(() => Observable.create((observer) => {
            let reader = new FileReader();
            reader.onerror = evt => {
                this.zone.run(() => observer.error(evt));
            };
            reader.onloadend = evt => {
                this.zone.run(() => observer.next(evt));
            };
            switch (mode) {
                case "text":
                    reader.readAsText(file);
                    break;
                case "arrayBuffer":
                    reader.readAsArrayBuffer(file);
                    break;
                case "binaryString":
                    reader.readAsBinaryString(file);
                    break;
                case "dataURL":
                    reader.readAsDataURL(file);
                    break;
            }
        }));
    }
}
Es posible que necesite importar ngZone, ya que la retrollamada puede ejecutarse fuera del área de ángulo, evitando así la detección de cambios.