반응형

service나 module은 기보적으로 싱글턴으로 작동한다.

하지만 여기서는 클래스 단위의 싱글턴을 사용할 것이다.

 

시간을 yyyyMMdd패턴으로 바꾸어주는 클래스를 예시로 들어보겠다.

namespace 와 export 키워드를 반드시 사용한다.

// date-formatter.ts

export namespace DateFormatterSingleton {  

    export function nowYYYYmmDD():string {
        let _temp = new Date();
        return _yyyyMMdd(_temp);
    }

    export function toYYYYmmDD(date: string):string {
        let _temp = new Date(date);
        return _yyyyMMdd(_temp);
    }

    function _yyyyMMdd(date: Date) {
        return date.getFullYear()+'-'
        +_toTwoDigits((date.getMonth()+1).toString())+'-'
        +_toTwoDigits(date.getDate().toString());
    }

    function _toTwoDigits(numeric: string):string {
        return numeric.length == 1 ? "0"+numeric : numeric;
    }
}

 

사용방법

import { DateFormatterSingleton } from 'src/app/model/date-formatter';

datePicker: string = DateFormatterSingleton.nowYYYYmmDD();

위 코드와 같이 사용하면된다. Java에서와 같이 getInstance()와 같은 호출은 필요없다.

반응형
반응형

1. modal page 생성

2. 상위 module에 import 'modal page'

3. modal page 코드 작성

 

Ionic5 Angular 기반으로 작성하였습니다.


1. modal page 생성

// cli로 하는 경우, 명령어를 입력해 생성합니다.
ionic generate page modal-exam

generate page를 사용하면, 4개의 파일이 생성됩니다.

module.ts, html, scss, ts

// modal-exam.module.ts

const routes: Routes = [
  {
    path: 'modal-exam',
    component: ModalExamPage
  }
];

@NgModule({
  imports: [
	...
  ],
  declarations: [ModalExamPage],
  exports: [ModalExamPage]
})
export class ModalExamPageModule {}

[route 사용하는 경우]

반드시 path에 위치를 기입해주세요.


2. 상위.module에 NgModule에 등록하기

// home.module.ts

... 
@NgModule({
  imports: [
	...
    ModalExamPage
  ],
})
export class HomeModule { }

3. modal page 코드 작성

<!-- modal-exam.html -->

<div class="ion-page">
  <ion-header>
    <ion-toolbar>
      <ion-buttons slot="end">
        <ion-button (click)="closeModal()">닫기</ion-button>
      </ion-buttons>
      <ion-title>{{data}}</ion-title>
    </ion-toolbar>
  </ion-header>
  <ion-content class="ion-padding">
    <ion-item>
      내용을 추가하세요
    </ion-item> 
  </ion-content>
</div>
// modal-exam.page.ts

import { Component, Input, OnInit } from '@angular/core';
import { ModalController } from '@ionic/angular';

@Component({
  selector: 'app-modal-exam',
  templateUrl: './modal-exam.page.html',
  styleUrls: ['./modal-exam.page.scss'],
})
export class EditInfoPage implements OnInit {
  
  @Input() data: string;

  constructor(public modalController: ModalController) { }

  ngOnInit() {}

  closeModal() {
    this.modalController.dismiss({
      'dismissed': true
    });
  }

}
<!-- home.component.html -->
<div class="ion-page">
  <ion-header [translucent]="true">
    <ion-toolbar>
    <ion-title>
      모달 예제
    </ion-title>
    </ion-toolbar>
  </ion-header>
  <ion-content class="ion-padding" [fullscreen]="true">
    <ion-item >
      <ion-label>수정하기</ion-label>
      <ion-button color="success" slot="end" (click)="editLocation()">
        <ion-icon name="arrow-forward"></ion-icon>
      </ion-button>
    </ion-item>
  </ion-content>
</div>
// home.component.ts

import { Component, OnInit } from '@angular/core';
import { ModalController } from '@ionic/angular';

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

constructor(public modalController: ModalController) { }

  ngOnInit() {}
  
  async presentModal() {
    const modal = await this.modalController.create({
      component: EditInfoPage,
      componentProps: {
        'data': 'modal-example'
      }
    });

    modal.onDidDismiss().then((res:any) => {
      if (res !== null) {
        console.log('Modal Sent Data : '+ res.data);
      }
    });

    return await modal.present();
  }

}
반응형
반응형

html 세팅

<!-- child component HTML -->
<ion-searchbar autocomplete="on" [(ngModel)]="searchbarInput" (ionInput)="filterItems($event)"
  debounce="500">
</ion-searchbar>

<ion-list *ngIf="listActive">
  <ion-item *ngFor="let item of items" (click)="fillSearchbarText(item.title)" style="cursor: pointer;">
    <ion-label>
      <strong>{{item.title}}</strong>
    </ion-label>
  </ion-item>
</ion-list>

<ion-searchbar

autocomplete="on" : 자동완성 기능을 사용합니다.

[(ngModel)]="searchbarInput" : searchbarInput과 ion-searchbar의 input을 2-way바인딩 합니다.

(ionInput)="filterItems($event)" : Input에 입력될 때 마다 filterItems() 메쏘드를 실행합니다.

debounce="500" : (ionInput)의 작동 시간에 반응 시간을 설정합니다. (기본은 250)

 

<ion-list *ngIf="listActive" : ion-list를 표시할 때 쓰는 flag입니다.

<ion-item *ngFor="let item of items" : filterItems로 필터링 된 값을 뿌립니다.

<ion-item (click)="fillSearchbarText(item.title)" : 해당 아이템의 값을 바인딩된 searchbarInput에 넣습니다.

 

// child component ts file
import { Component, Input, ViewChild, Output, EventEmitter } from '@angular/core';
import { DeviceCommon, ItemView } from '../device-common';

class ItemView {
  title: string
}

@Component({
  selector: 'app-autocomplete-searchbar',
  templateUrl: './autocomplete-searchbar.component.html',
  styleUrls: ['./autocomplete-searchbar.component.scss'],
})
export class AutocompleteSearchbarComponent {

  @Input() itemViewArr: ItemView[];
  @Output() itemSelected = new EventEmitter<string>();
  @ViewChild('', { static: true }) searchbarInput: string;

  private listActive = false;
  private items: ItemView[] = [];

  constructor(private common: DeviceCommon) { }

  initializeItems() {
    this.items = [...this.itemViewArr];
  }

  includeAnySpell = (result: ItemView[], item: ItemView, term: string) => {
    const include = (str: string) => str.toLowerCase().indexOf(term.toLowerCase()) > -1;
    if (include(item.title)) {
      result.push(item.title)
    }
    return result;
  }

  filterItems(ev: any) {
    this.initializeItems();
    const term: string = ev.target.value;
    if (term && term.trim() != '') {
      this.listActive = true;
      this.items = this.items.reduce((result: ItemView[], item: ItemView) => this.includeAnySpell(result, item, term), []);
    } else {
      this.listActive = false;
    }
  }

  fillSearchbarText(title: string) {
    this.searchbarInput = title;
    this.listActive = false;
    this.itemSelected.emit(title);
  }

}

@Input() itemViewArr: ItemView[]; : 부모 컴포넌트에서 받은 property값입니다.

@Output() itemSelected = new EventEmitter<string>(); : 부모 컴포넌트에 보낼 이벤트입니다.

@ViewChild('', { static: true }) searchbarInput: string; : [(ngModel)]="searchbarInput" 바인딩을 선언합니다.

 

  initializeItems() {
    this.items = [...this.itemViewArr];
  }

 

 

외부에서 받은 itemViewArr값을 this.items에 복사하여 넣습니다.

 

  includeAnySpell = (result: ItemView[], item: ItemView, term: string) => {
    const include = (str: string) => str.toLowerCase().indexOf(term.toLowerCase()) > -1;
    if (include(item.title)) {
      result.push(item.title)
    }
    return result;
  }

  filterItems(ev: any) {
    this.initializeItems();
    const term: string = ev.target.value;
    if (term && term.trim() != '') {
      this.listActive = true;
      this.items = this.items.reduce((result: ItemView[], item: ItemView) => this.includeAnySpell(result, item, term), []);
    } else {
      this.listActive = false;
    }
  }

includeAnySpell = (result: ItemView[], item: ItemView, term: string) => {...} : Array.reduce에 사용할 함수 선언합니다.

const include = (str: string) => str.toLowerCase().indexOf(term.toLowerCase()) > -1; : input에서 입력된 값중에 한글자라도 포함되면 true 를 반환하는 함수입니다.

 

filterItems(ev: any) : <ion-searchbar (ionInput)="filterItems($event)" 로써 입력될 때 마다 작동합니다.

this.initializeItems(); : 아이템을 초기화합니다.

const term: string = ev.target.value; : input에 입력된 값을 가져옵니다.

 

fillSearchbarText(title: string) {
    this.searchbarInput = title;
    this.listActive = false;
    this.itemSelected.emit(title);
  }

<ion-item 을 클릭했을 때 작동하는 메쏘드 입니다.

this.searchbarInput=title; : 해당 item의 값을 input에 입력합니다.

this.itemSelected.emit(title); : 선택된 값을 부모 컴포넌트에 전달합니다.

 

<!-- parent component HTML -->

<app-autocomplete-searchbar [itemViewArr]="itemViewArr" (itemSelected)="autocompletedValue($event)"
</app-autocomplete-searchbar>

<app-autocomplete-searchbar  : 위의 child component 입니다.

[itemViewArr]="itemViewArr" : child component에서 @Input으로 받을 값 입니다.

[itemViewArr] : child component에서 사용할 property값 입니다.

"itemViewArr" : parent component에서 보내는 ts 값입니다.

 

(itemSelected)="autocompletedValue($event)" :

(itemSelected) : child component의 itemSelected(EventEmitter).emit()이 실행될 때 

"autocompletedValue($event)" : parent component에서 실행 될 메쏘드로 child component에서 값을 받습니다.

 

// parent component ts
itemViewArr: ItemView[] = [];

setItemView() {
this.itemViewArr = [];
  this.msgHouse.msgHouse.forEach(msgRoom => {
    this.itemViewArr.push(new ItemView(msgRoom.title));
  })
}

autocompletedValue(title: string) {
    if (title && title.length) {
	  console.log(title);
    }
  }

 

setItemView() {...} : child component로 들어갈 this.itemViewArr을 채웁니다.

 

autocompletedValue(title: string) : child component에서 보낸 값을 받는 메쏘드 입니다.

 

응용을 하면 아래와 같은 화면도 가능합니다.

f를 입력했을 경우, f가 포함된 모든 단어들이 다 나오도록 할 수 있습니다.

 

반응형

'프로그래밍 > Ionic' 카테고리의 다른 글

아이오닉 form handling  (0) 2020.02.14
Ionic 4 배포하기  (0) 2019.11.08
DataHandling  (0) 2019.10.18
State 관리  (0) 2019.10.12
Styling & Theming  (0) 2019.10.12

+ Recent posts