반응형

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