Web/ionic

[Angular] ionic Storage 라이브러리 사용하기

WakaraNai 2021. 11. 24. 21:47
728x90
반응형

powershell에 storage 라이브러리 설치하기

npm install --save @ionic/storage-angular

 

 

Angular JS 버전으로 ionic을 빌드한 경우

app.module.ts에 설치한 라이브러리 불러오기

import { IonicStorageModule } from '@ionic/storage-angular';


 IonicStorageModule.forRoot() // @NgModule의 imports 리스트에 추가로 적기

 

 

Item DTO class 구체화하기

cmd에서

ionic g -> class -> classes/item 

 

classes폴더의 item.ts 파일 수정

export class Item {
    id: string;
    name: string;
}

 

적용하기 - Dependency Injection

cmd에서

ionic g -> service   -> services/item 

 

생성된 services 폴더의 item.service.ts 파일 수정하기

import { Injectable } from '@angular/core';
import { Storage } from '@ionic/storage-angular';
import { Item } from "../classes/item";

@Injectable({
  providedIn: 'root'
})


export class ItemService {

  public items: Item[] = [];
  
/////////////////////
//// stroage 관련 내용
  private _storage: Storage | null = null;

  constructor(private storage: Storage) {
    this.init();
   }
  async init() {
    const storage = await this.storage.create();
    this._storage = storage;
  }

  public set(key:string, value:any) {
    this._storage?.set(key, value);
  }
///////////////

  getItems() {
    return new Promise((resolve) => {
      this.storage.get('items').then((result) =>{
        if (result) {this.items = result;}
        resolve(true);
      });
    });
    
  }

  saveItems() {
    console.log(this.items);
    this.storage.set('items', this.items);
  }

  getItem(id: string) {
    return this.items.find(item => item.id == id);
  }

  addItem(item: Item) {
    this.items.push(item);
    this.saveItems();
  }

  deleteItem(item: Item) {
    this.items.splice(this.items.indexOf(item), 1);
    this.saveItems();
  }
}

 

 

Item Page 생성하기

cmd에서

ionic g -> page -> item

 

item폴더의 item.page.ts 파일 수정

import { Component, OnInit } from '@angular/core';
import { Item } from '../classes/item';
import { ItemService } from '../services/item.service';
import { ActivatedRoute } from '@angular/router';
import { NavController } from '@ionic/angular';
import { Storage } from '@ionic/storage-angular';

@Component({
  selector: 'app-item',
  templateUrl: './item.page.html',
  styleUrls: ['./item.page.scss'],
})

export class ItemPage implements OnInit {
  private item: Item;
  private editable: boolean = false;

  constructor(
    private route: ActivatedRoute,
    private itemService: ItemService,
    private navCtrl: NavController) {
    this.item = {
      id: '',
      name: ''
    };
   }
  ngOnInit() {
    let id = this.route.snapshot.paramMap.get('id');

    if (id) { // 수정하는 거라면
      this.itemService.getItems().then(() => {
        this.editable = true;
        this.item = this.itemService.getItem(id);
      });

    }
  }

  // on button in item.page.html
  saveItem() {
    console.log(this.item);
    if (this.editable) {
      this.itemService.saveItems();
    }  else {
      this.itemService.addItem(this.item);
    }

    // angular 의 navigation controller - 
    this.navCtrl.navigateBack('/home');
  }

}

 

item.page.html 수정

<ion-header>
    <ion-toolbar>
        <ion-title>item</ion-title>
    </ion-toolbar>
</ion-header>

<ion-content>
    <ion-item>
        <ion-label position="floating">ID</ion-label>
        <ion-input type="text" [(ngModel)]="item.id"></ion-input>
    </ion-item>

    <ion-item>
        <ion-label position="floating">Name</ion-label>
        <ion-input type="text" [(ngModel)]="item.name"></ion-input>
    </ion-item>

    <ion-button expand="block" (click)="saveItem()">Save</ion-button>
</ion-content>

 

 

 

Home Page 생성 - 리스트 항목 출력

cmd에서

ionic g -> page -> home

 

 

home.page.html

<ion-header>
    <ion-toolbar>
        <ion-title>home</ion-title>
        <ion-buttons slot="end">
            <!-- 버튼 여러 개 추가하고 싶을 때 -->
            <ion-button color="light" fill="outline" routerLink="item" routerDirection="forward">
                <!-- routerDirection은 애니메이션이 달라짐 -->
                <ion-item name="add"></ion-item> Add
            </ion-button>
        </ion-buttons>
    </ion-toolbar>
</ion-header>

<ion-content>

    <ion-card class="welcome-card">
        <ion-item lines="none">
            <ion-thumbnail slot="start">
                <img src="/assets/favicon.png">
            </ion-thumbnail>
            <ion-label>
                Pet List Sample Application
                <p>This is the Blueprint Application, which deliver a set of basic skills regarding Ionic.</p>
            </ion-label>
        </ion-item>
    </ion-card>

    <ion-list lines="none">
        <ion-item-sliding *ngFor="let item of itemService.items">
            <ion-item>
                <ion-label>{{item.name}}</ion-label>
            </ion-item>
            <ion-item-options side="end">
                <ion-item-option color="primary" (click)="updateItem(item.id)" expandable>
                    <ion-icon slot="start" name="swap"></ion-icon> Update
                </ion-item-option>
                <ion-item-option color="secondary" (click)="deleteItem(item)">
                    <ion-icon slot="start" name="trash"></ion-icon> Delete
                </ion-item-option>

            </ion-item-options>
        </ion-item-sliding>
    </ion-list>

</ion-content>

 

 

home.page.ts

import { Component, OnInit } from '@angular/core';
import { NavController } from '@ionic/angular';
import { ItemService } from '../services/item.service';
import { Item } from '../classes/item';

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

  constructor(public itemService: ItemService,
              private navCtrl: NavController) {

               }

  updateItem(id: string) {
    this.navCtrl.navigateBack('item/'+id); // 애니메이션 넣으면서 nav하기
  }

  deleteItem(item: Item){ // item 객체
    this.itemService.deleteItem(item);

  }
  ngOnInit() {
  }

}

 

 

마지막으로 routing 설정 다시 확인하기

 

app-routing.module.ts

import { NgModule } from '@angular/core';
import { PreloadAllModules, RouterModule, Routes } from '@angular/router';

const routes: Routes = [
  {
    path: '',
    redirectTo: 'folder/Inbox',
    pathMatch: 'full'
  },
  {
    path: 'folder/:id',
    loadChildren: () => import('./folder/folder.module').then( m => m.FolderPageModule)
  },
  {
    path: 'item',
    loadChildren: () => import('./item/item.module').then( m => m.ItemPageModule)
  },
  {
    path: 'item/:id',
    loadChildren: () => import('./item/item.module').then( m => m.ItemPageModule)
  },
  {
    path: 'home',
    loadChildren: () => import('./home/home.module').then( m => m.HomePageModule)
  }
];

@NgModule({
  imports: [
    RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })
  ],
  exports: [RouterModule]
})
export class AppRoutingModule {}

 

Splash Screen, StatusBar 설치

# https://ionicframework.com/docs/v3/native/splash-screen/
ionic cordova plugin add cordova-plugin-splashscreen 
npm install @awesome-cordova-plugins/splash-screen 
#npm install --save @ionic-native/splash-screen

# https://ionicframework.com/docs/native/status-bar
ionic cordova plugin add cordova-plugin-statusbar 
npm install @awesome-cordova-plugins/status-bar
# npm install --save @ionic-native/status-bar

 

app.component.ts

import { Component } from '@angular/core';
import { Platform } from '@ionic/angular';
import { ItemService } from './services/item.service';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar }from '@ionic-native/status-bar/ngx'
import { Storage } from '@ionic/storage-angular';

@Component({
  selector: 'app-root',
  templateUrl: 'app.component.html',
  styleUrls: ['app.component.scss'],
})
export class AppComponent {
  public appPages = [
    { title: 'Home', url: '/home', icon: 'home' },
    { title: 'Add', url: '/item', icon: 'add' },

    { title: 'Inbox', url: '/folder/Inbox', icon: 'mail' },
    { title: 'Outbox', url: '/folder/Outbox', icon: 'paper-plane' },
    { title: 'Favorites', url: '/folder/Favorites', icon: 'heart' },
    { title: 'Archived', url: '/folder/Archived', icon: 'archive' },
    { title: 'Trash', url: '/folder/Trash', icon: 'trash' },
    { title: 'Spam', url: '/folder/Spam', icon: 'warning' },
  ];
  
  public labels = ['Family', 'Friends', 'Notes', 'Work', 'Travel', 'Reminders'];
  
  constructor(
    private platform: Platform,
    private splashScreen: SplashScreen ,
    private statusBar: StatusBar,
    private itemService: ItemService,
    private storage: Storage,
  ) {
    this.initApp();
  }

  initApp() {
    this.itemService.getItems();
    this.platform.ready().then(() => {
      this.statusBar.styleDefault();
      this.splashScreen.hide();
    })
  }

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

 

app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouteReuseStrategy } from '@angular/router';

import { IonicModule, IonicRouteStrategy } from '@ionic/angular';

import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';

import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar } from '@ionic-native/status-bar/ngx';
import { IonicStorageModule } from '@ionic/storage-angular';

@NgModule({
  declarations: [AppComponent],
  entryComponents: [],
  imports: [
    BrowserModule,
    IonicModule.forRoot(),
    AppRoutingModule,
    IonicStorageModule.forRoot(),
  ],
  providers: [
    SplashScreen,
    StatusBar,
    { provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
  ],
  bootstrap: [AppComponent],
})
export class AppModule {}

 

+) 이런 형태의 에러가 발생한다면,

app.module.ts의 provider에 그 대상을 적어주지 않았다는 것

R3InjectorError(AppModule)[SplashScreen -> SplashScreen -> SplashScreen]: 
  NullInjectorError: No provider for SplashScreen!

 

 


결과

 

 
728x90
반응형