Класс Singleton не работает с компонентной навигацией - PullRequest
0 голосов
/ 17 июня 2019

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

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

Вот мой код на данный момент couchbase.service.ts

import { Injectable } from "@angular/core";
import { Couchbase } from "nativescript-couchbase";
import * as connection from "tns-core-modules/connectivity";
import { isAndroid } from "platform";

@Injectable()
export class CouchbaseService {
    private static database: any;

    constructor() {
        console.log("enter constructor")
    }

    public static init(){
        if(!CouchbaseService.database) {
            console.log("enter init")
            CouchbaseService.database = new Couchbase("data");
        }
        return CouchbaseService.database;
    }

    public getDatabase() {
        return CouchbaseService.database;
    }
    ...

}

app.component.ts: я прочиталчто вызов init из этого родительского класса заставит приложение сохранить его для детей (обратите внимание, что я также попытался передать CouchbaseService в качестве параметра конструктора, изменив метод init на нестатический)

import { Component } from "@angular/core";
import * as Platform from "platform";
import { CouchbaseService } from './services/couchbase.service';

@Component({
    selector: "ns-app",
    templateUrl: "app.component.html",
})

export class AppComponent { 
    constructor() {
        CouchbaseService.init();
    }
}

В моем файле app.module.ts я добавил CouchbaseService в список providers.

import { NgModule, ErrorHandler, NO_ERRORS_SCHEMA } from "@angular/core";
import { NativeScriptModule } from "nativescript-angular/nativescript.module";
import { NativeScriptUIListViewModule } from "nativescript-ui-listview/angular";
import { NativeScriptUISideDrawerModule } from "nativescript-ui-sidedrawer/angular";
import { NativeScriptHttpModule } from "nativescript-angular/http";
import { Http } from "@angular/http";
import { NativeScriptUIDataFormModule } from "nativescript-ui-dataform/angular";
import { NativeScriptFormsModule } from "nativescript-angular/forms";
import { registerElement } from 'nativescript-angular/element-registry';
import { CardView } from 'nativescript-cardview';
import { AppRoutingModule } from "./app.routing";
import { AppComponent } from "./app.component";

import { CouchbaseService } from "./services/couchbase.service";


import { HomeComponent } from "./components/home/home.component";
registerElement('CardView', () => CardView);
registerElement("MapboxView", () => require("nativescript-mapbox").MapboxView);
registerElement("Fab", () => require("nativescript-floatingactionbutton").Fab);

@NgModule({
    bootstrap: [
        AppComponent
    ],
    imports: [
        NativeScriptModule,
        NativeScriptUIListViewModule,
        NativeScriptUISideDrawerModule,
        AppRoutingModule,
        NativeScriptUIDataFormModule,
        NativeScriptFormsModule,
        NativeScriptHttpModule
    ],
    declarations: [
        AppComponent,
        HomeComponent
    ],
    providers: [
        CouchbaseService,
    ],
    schemas: [
        NO_ERRORS_SCHEMA
    ],
    entryComponents: [
    ],
})
/*
Pass your application module to the bootstrapModule function located in main.ts to start your app
*/
export class AppModule { }

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

Я использую NativeScript 4 с Angular 5 и TypeScript 2.7.2.

1 Ответ

1 голос
/ 17 июня 2019

Это не то, как следует использовать одноэлементную услугу.Давайте сделаем так:

Измените ваш сервис следующим образом:

import { Injectable } from "@angular/core";
import { Couchbase } from "nativescript-couchbase";
import * as connection from "tns-core-modules/connectivity";
import { isAndroid } from "platform";

@Injectable()
export class CouchbaseService {

    private database: any;

    constructor() {
        console.log("enter constructor")
        this.init();
    }

    private init(){
        if(!this.database) {
            console.log("enter init")
            this.database = new Couchbase("data");
        }
    }

    public getDatabase() {
        return this.database;
    }
    ...

}

В вашем AppModule [или модуле, где у вас есть сервис] укажите сервис в провайдере @NgModuleмассив, подобный этому:

@NgModule({
  declarations: [
    AppComponent,
    YourComponent
  ],
  imports: [
    BrowserModule
  ],
  providers: [CouchbaseService],
  bootstrap: [AppComponent]
})
export class AppModule { }

Теперь в вашем компоненте используйте инъекцию зависимости конструктора следующим образом:

import { Component } from "@angular/core";
import * as Platform from "platform";
import { CouchbaseService } from './services/couchbase.service';

@Component({
    selector: "ns-app",
    templateUrl: "app.component.html",
})

export class AppComponent { 
    constructor(private service: CouchbaseService) {
        console.log(this.service.getDatabase());
    }
}
...