簡體   English   中英

離子存儲:TypeError:無法讀取未定義的屬性“獲取”

[英]Ionic Storage : TypeError: Cannot read property 'get' of undefined

從長遠來看,我正在使用 Ionic Storage 來存儲數據。 現在我想在我 go 到統計頁面時檢索數據,所以我調用了我創建的服務並在統計頁面的 ngOnInit 中編寫了方法,但是如果我正確理解了這個問題,它無法識別存儲 class 的實例化但奇怪的是,當我在 ionViewWillEnter() 中編寫方法時它確實有效。 我使 ngOnInit 和 ionViewWillEnter 都異步,但我仍然收到 ngOnInit 錯誤。 如果我沒記錯的話,我可以用 ionViewWillEnter 技巧 go 它類似於在我的用例中調用 ngOnInit 中的方法,但我仍然很好奇它為什么會出錯......

統計頁面的TS:

import { StatsService } from './../service/stats.service';
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-statistics',
  templateUrl: './statistics.page.html',
  styleUrls: ['./statistics.page.scss'],
})
export class StatisticsPage implements OnInit {

  testsAmount: any = 0;

  constructor(public statsService: StatsService) {}

  addJohn(){
    this.statsService.set("1", "john");
  }

  removeAll(){
    this.statsService.clearAll();
  }

  async getJohn(){
    console.log(await this.statsService.get("1"));
  }

  

  async ngOnInit() {
      await this.statsService.set("testSetngOnInit", "blabla");
      console.log("testSet initialized from the ngOnInit");
      console.log(await this.statsService.get("testSetngOnInit"));
  }

  async ionViewWillEnter(){
    await this.statsService.set("testSetionViewWillEnter", "blabla");
      console.log("testSet initialized from the ionViewWillEnter");
    console.log(await this.statsService.get("testSetionViewWillEnter"));
  }

  

}

服務的TS:

import { Injectable } from '@angular/core';
import { Storage } from '@ionic/storage-angular';
import * as CordovaSQLiteDriver from 'localforage-cordovasqlitedriver';

@Injectable({
  providedIn: 'root'
})
export class StatsService {
  
  // private _storage: Storage | null = null;
  private _storage: Storage;

  constructor(public storage: Storage) { 
    this.init();
  }

  async init() {
    // If using, define drivers here: await this.storage.defineDriver(/*...*/);
    await this.storage.defineDriver(CordovaSQLiteDriver);
    const storage = await this.storage.create();
    this._storage = storage;
  }

  async keyExistence(key: string){
    if(await this.get(key) == null){
      return false;
    }
    else{
      return true;
    }
  }

  // Create and expose methods that users of this service can
  // call, for example:
  async set(key: string, value: any) {
    await this._storage?.set(key, value);
  }

  async clearAll() {
    await this._storage.clear();
  }

  async get(key: string) {
    return await this._storage.get(key);
  }

}

這就是我在控制台中得到的: 安慰

還有我的索引數據庫:

索引數據庫

提前致謝 !

錯誤消息表明 stats.service.ts 中的第 44 行是導致問題的行。 您的組件ngOnInit確實在訪問服務實例,但服務本身失敗了。 我想這是因為您的StatsService構造函數正在調用this.init(); ,但構造函數並沒有等待它(我認為它不能)。 因此,當您嘗試在早期(在 ngOnInit 中)訪問它時, this._storage尚未初始化。

statsService.set似乎成功的原因是因為該方法調用this._storage?.set(key, value) - 注意? 這是一個 null 條件,這意味着如果_storage是 null 則整個表達式的計算結果為null

我不確定,但我假設ionViewWillEnter在組件生命周期的后期被調用,並且統計服務構造函數有足夠的時間來完全初始化。 另一方面, ngOnInit在組件構造函數之后被調用。

好吧,我找到了答案,這其實很容易解決。 太愚蠢了,我沒想到..,因此,與其在自己的 class 中實例化服務,不如在使用它的 class 中實例化它:所以在我的情況下:

我在服務構造函數中的內容:

constructor(public storage: Storage) { 
    this.init();
  }

但問題是構造函數不能使用異步語句,所以你不能告訴你的 class 等待它,所以你需要在 class 的 ngOnInit 中使用它來初始化:

我使用該服務的頁面:

async ngOnInit() {
      await this.statsService.init();
  }

希望這會幫助一些人:)

在 AppComponent 中調用 init 以創建存儲實例。 這應該只調用一次。

export class AppComponent implements OnInit,{

  constructor(
    private storage: StorageService
    ) {}

  async ngOnInit() {
    await this.storage.init();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM