Подтвердить что ты не робот

Синглтоны в ионном 3, Angular 4

Я определяю службу как класс, что-то вроде этого:

@Injectable()
export class MyService {
 ...
}

В других компонентах или страницах я импортирую этот класс только с командой импорта.

import { MyService } from '../pages/services/myservice';

В конструкторе:

constructor(public _MyService: MyService)

В моем основном app.module.ts я добавил этот сервис класса как поставщика.

providers: [someOtherThings, MyService, someOtherThings]

В Ionic 2 все работает так, как ожидалось. Сервис однотонный.

Но в Ionic 3, который использует angular 4, похоже, что каждый компонент создает новый экземпляр этого класса.

Есть ли какой-либо новый способ создания классов сервисов singleton в angular 4?

4b9b3361

Ответ 1

Im использует ионный 3 с lazyload a angular 4 и не имеет проблем. Чтобы сделать его singleton, убедитесь, что ваш модуль приложения предоставляет эту услугу. и удалите поставщиков @Component, которые используют эту службу.

Модуль приложения

@NgModule({
  ...

  providers: [
    StatusBar,
    SplashScreen,
    { provide: ErrorHandler, useClass: IonicErrorHandler },
    Singleton // the service or provider to be single ton
  ]
})
export class AppModule { }

Служба

import { Injectable } from '@angular/core';
import 'rxjs/add/operator/map';

@Injectable()
export class Singleton {

  data = "init data";
  constructor() {
    console.log('Hello Singleton Provider');
  }

  set(data){
    this.data = data;
  }

  log(){
    console.log(this.data);   
  }
}

Tes Служить на ионной странице

Первая страница

import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { Singleton } from '../../providers/singleton';

@IonicPage()
@Component({
  selector: 'page-first',
  templateUrl: 'first.html'
})
export class FirstPage {
  constructor(public navCtrl: NavController, public navParams: 
  NavParams,private single:Singleton) {
  }

  ionViewDidLoad() {
    console.log('ionViewDidLoad First');
    this.single.log(); // log init data;
    this.single.set("First singleton data");
  }

}

Вторая страница

import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { Singleton } from '../../providers/singleton';

@IonicPage()
@Component({
  selector: 'page-second',
  templateUrl: 'second.html'
})
export class SecondPage {
  constructor(public navCtrl: NavController, public navParams: 
  NavParams,private single:Singleton) {
  }

  ionViewDidLoad() {
    console.log('ionViewDidLoad Second');
    this.single.log(); // log First singleton data
  }

}

Третья страница создает новый экземпляр, если поставщики добавили компонент

import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { Singleton } from '../../providers/singleton';

@IonicPage()
@Component({
  selector: 'page-second',
  templateUrl: 'second.html',
  providers:[Singleton] // wrong because its create a new instance
})
export class ThirdPage {
  constructor(public navCtrl: NavController, public navParams: 
  NavParams,private single:Singleton) {
  }

  ionViewDidLoad() {
    console.log('ionViewDidLoad ThirdPage');
    this.single.log(); // log init data
  }

}

обязательно удалите поставщиков на компоненте, чтобы сделать его одиночным.

Ответ 2

Попробуйте сохранить экземпляр службы в своем AppModule и получить экземпляр (вместо его запуска) позже в других компонентах.

import {Injector} from '@angular/core';

export class AppModule {
    // Allows for retrieving singletons using 'AppModule.injector.get(MyService)' later in the code

    static injector: Injector;

    constructor(injector: Injector) {
        AppModule.injector = injector;
    }
}

И для извлечения экземпляра службы используйте:

const myService = AppModule.injector.get(MyService);

Проверьте документацию Здесь!

Ответ 3

В моем случае это имеет какое-то отношение к ReflectiveInjector.

У меня есть две службы A и B, каждая из которых должна быть однопользовательской службой, ссылающейся друг на друга.

Если я вставляю их в другой конструктор, это может вызвать компиляцию ошибки из-за циклической ссылки.

Если я использую

const injector = ReflectiveInjector.resolveAndCreate([AService]);
const a = injector.get(AService);

в конструкторе B, он сделает другой экземпляр A.

И нужно решить, сделав CService, содержащую данные, и AService и BService могут получить доступ к данным через CService.