Iako sam već objavio blog post na temu Ionic 3 autocomplete funkcionalnosti mislim da će vam se primjer iz ovog blog posta još više svidjeti. Cijela se funkcionalnost temelji na proširivanju mogućnosti već postojeće Ionic Select komponente.
Postavljanje aplikacije
Za početak je potrebno kreirati novi Ionic projekt
|
1 2 |
$ ionic start Ionic3SelectSearchAutocomplete blank $ cd Ionic3SelectSearchAutocomplete |
Izrada select komponente
Komponentu možete kreirati sljedećom naredbom:
|
1 |
$ ionic generate component select-search |
Struktura datoteka sada izgleda ovako:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
--src - app - assets - components - select-search - select-search-module.ts - select-search-page.html - select-search-page.scss - select-search-page.ts - select-search.html - select-search.scss - select-search.ts - pages - theme - ... |
Sadržaj datoteka možete vidjeti u nastavku.
select-search-module.ts
Ovdje definiramo modul koji će Ionic aplikaciji reći od čega se sastoji naša Ionic komponenta te kako ju aplikacija prilikom pokretanja treba interpretirati.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
import { NgModule } from '@angular/core'; import { IonicPageModule } from 'ionic-angular'; import { SelectSearch } from './select-search'; import { SelectSearchPage } from './select-search-page'; @NgModule({ declarations: [ SelectSearch, SelectSearchPage ], imports: [ IonicPageModule.forChild(SelectSearch), IonicPageModule.forChild(SelectSearchPage) ], exports: [ SelectSearch, SelectSearchPage ], entryComponents: [ SelectSearch, SelectSearchPage ] }) export class SelectSearchModule { } |
select-search-page.html
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
<ion-header> <ion-navbar> <ion-title>{{selectComponent.title}}</ion-title> </ion-navbar> <ion-toolbar *ngIf="selectComponent.canSearch"> <ion-searchbar #searchbarComponent [(ngModel)]="selectComponent.filterText" (ionInput)="filterItems()" [placeholder]="selectComponent.searchPlaceholder || 'Search'"> </ion-searchbar> </ion-toolbar> </ion-header> <ion-content> <div class="select-search-spinner" *ngIf="selectComponent.isSearching"> <div class="select-search-spinner-background"></div> <ion-spinner></ion-spinner> </div> <ion-list no-margin *ngIf="filteredItems.length"> <button ion-item detail-none *ngFor="let item of filteredItems" (click)="select(item)"> <ion-icon [name]="isItemSelected(item) ? 'checkmark-circle' : 'radio-button-off'" [color]="isItemSelected(item) ? 'primary' : 'daek'" item-left> </ion-icon> <h2>{{selectComponent.formatItem(item)}}</h2> </button> </ion-list> <div *ngIf="!filteredItems.length" margin>No items found.</div> </ion-content> <ion-footer *ngIf="selectComponent.canReset || selectComponent.multiple"> <ion-toolbar padding> <ion-row> <ion-col no-padding *ngIf="selectComponent.canReset" [attr.col-6]="selectComponent.canReset && selectComponent.multiple ? '' : null" [attr.col-12]="selectComponent.canReset && !selectComponent.multiple ? '' : null"> <button ion-button full no-margin (click)="reset()" [disabled]="!selectedItems.length"> Clear </button> </ion-col> <ion-col no-padding *ngIf="selectComponent.multiple" [attr.col-6]="selectComponent.canReset && selectComponent.multiple ? '' : null" [attr.col-12]="!selectComponent.canReset && selectComponent.multiple ? '' : null"> <button ion-button full no-margin (click)="ok()"> OK </button> </ion-col> </ion-row> </ion-toolbar> </ion-footer> |
select-search-page.scss
|
1 2 3 4 5 6 7 8 9 10 11 |
.select-search-page { &.select-search-page-can-reset.select-search-page-multiple { .footer .col:first-child { padding-right: $content-margin / 2; } .footer .col:last-child { padding-left: $content-margin / 2; } } } |
select-search-page.ts
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
import { Component, ViewChild } from '@angular/core'; import { NavParams, NavController, Searchbar } from 'ionic-angular'; import { SelectSearch } from './select-search'; @Component({ selector: 'select-search-page', templateUrl: 'select-search-page.html', host: { 'class': 'select-search-page', '[class.select-search-page-can-reset]': 'selectComponent.canReset', '[class.select-search-page-multiple]': 'selectComponent.multiple' } }) export class SelectSearchPage { selectComponent: SelectSearch; filteredItems: any[]; selectedItems: any[] = []; navController: NavController; @ViewChild('searchbarComponent') searchbarComponent: Searchbar; constructor(private navParams: NavParams) { this.selectComponent = navParams.get('selectComponent'); this.navController = navParams.get('navController'); this.filteredItems = this.selectComponent.items; this.filterItems(); if (this.selectComponent.value) { if (this.selectComponent.multiple) { this.selectComponent.value.forEach(item => { this.selectedItems.push(item); }); } else { this.selectedItems.push(this.selectComponent.value); } } } ngAfterViewInit() { if (this.searchbarComponent) { // Focus after a delay because focus doesn't work without it. setTimeout(() => { this.searchbarComponent.setFocus(); }, 1000); } } isItemSelected(item: any) { return this.selectedItems.find(selectedItem => { if (this.selectComponent.itemValueField) { return item[this.selectComponent.itemValueField] === selectedItem[this.selectComponent.itemValueField]; } return item === selectedItem; }) !== undefined; } deleteSelectedItem(item: any) { let itemToDeleteIndex; this.selectedItems.forEach((selectedItem, itemIndex) => { if (this.selectComponent.itemValueField) { if (item[this.selectComponent.itemValueField] === selectedItem[this.selectComponent.itemValueField]) { itemToDeleteIndex = itemIndex; } } else if (item === selectedItem) { itemToDeleteIndex = itemIndex; } }); this.selectedItems.splice(itemToDeleteIndex, 1); } addSelectedItem(item: any) { this.selectedItems.push(item); } select(item: any) { if (this.selectComponent.multiple) { if (this.isItemSelected(item)) { this.deleteSelectedItem(item); } else { this.addSelectedItem(item); } } else { if (!this.isItemSelected(item)) { this.selectedItems = []; this.addSelectedItem(item); this.selectComponent.select(item); } this.close(); } } ok() { this.selectComponent.select(this.selectedItems.length ? this.selectedItems : null); this.close(); } close() { // Focused input interferes with the animation. // Blur it first, wait a bit and then close the page. if (this.searchbarComponent) { this.searchbarComponent._fireBlur(); } setTimeout(() => { this.navController.pop(); if (!this.selectComponent.hasSearchEvent) { this.selectComponent.filterText = ''; } }); } reset() { this.navController.pop(); this.selectComponent.reset(); } filterItems() { if (this.selectComponent.hasSearchEvent) { if (this.selectComponent.isNullOrWhiteSpace(this.selectComponent.filterText)) { this.selectComponent.items = []; } else { // Delegate filtering to the event. this.selectComponent.emitSearch(); } } else { // Default filtering. if (!this.selectComponent.filterText || !this.selectComponent.filterText.trim()) { this.filteredItems = this.selectComponent.items; return; } let filterText = this.selectComponent.filterText.trim().toLowerCase(); this.filteredItems = this.selectComponent.items.filter(item => { return item[this.selectComponent.itemTextField].toLowerCase().indexOf(filterText) !== -1; }); } } } |
select-search.html
|
1 2 3 4 5 6 |
<div class="select-search-label">{{title}}</div> <div class="select-search-value">{{formatValue()}}</div> <div class="select-search-icon"> <div class="select-search-icon-inner"></div> </div> <button aria-haspopup="true" ion-button="item-cover" class="item-cover"></button> |
select-search.scss
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
.item-select-search { .label { margin-right: 0; } } .select-search { display: flex; &-label { flex: 1; text-overflow: ellipsis; overflow: hidden; } &-value { max-width: 45%; text-overflow: ellipsis; overflow: hidden; } &-icon { position: relative; width: 20px; } &-icon-inner { position: absolute; top: 50%; left: 5px; border-top: 5px solid; border-right: 5px solid transparent; border-left: 5px solid transparent; pointer-events: none; } &-ios { .select-search-icon { height: 18px; } .select-search-icon-inner { margin-top: -2px; color: $select-ios-icon-color; } .select-search-value { padding-left: $select-ios-padding-left; } } &-md { .select-search-icon { height: 19px; } .select-search-icon-inner { margin-top: -3px; color: $select-md-icon-color; } .select-search-value { padding-left: $select-md-padding-left; } .select-search-label { color: $select-md-placeholder-color; } } &-spinner { &-background { top: 0; bottom: 0; left: 0; right: 0; position: absolute; background-color: #000; z-index: 100; opacity: 0.05; } ion-spinner { position: absolute; top: 50%; left: 50%; z-index: 10; margin-top: -14px; margin-left: -14px; } } } |
select-search.ts
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
import { Component, Input, Output, EventEmitter, Optional, OnDestroy, forwardRef, HostListener, OnChanges, SimpleChanges } from '@angular/core'; import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms'; import { Item, Form, NavController, Platform } from 'ionic-angular'; import { SelectSearchPage } from './select-search-page'; @Component({ selector: 'select-search', templateUrl: 'select-search.html', providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => SelectSearch), multi: true }], host: { 'class': 'select-search', '[class.select-search-ios]': 'isIos', '[class.select-search-md]': 'isMd', '[class.select-search-can-reset]': 'canReset' } }) export class SelectSearch implements ControlValueAccessor, OnDestroy, OnChanges { private _items: any[] = []; private isIos: boolean; private isMd: boolean; filterText = ''; value: any = null; hasSearchEvent: boolean; get items(): any[] { return this._items; } @Input('items') set items(items: any[]) { // The original reference of the array should be preserved to keep two-way data binding working between SelectSearchable and SelectSearchablePage. this._items.splice(0, this._items.length); // Add new items to the array. Array.prototype.push.apply(this._items, items); } @Input() isSearching: boolean; @Input() itemValueField: string; @Input() itemTextField: string; @Input() canSearch = false; @Input() canReset = false; @Input() title: string; @Input() searchPlaceholder: string = '...'; @Output() onChange: EventEmitter<any> = new EventEmitter(); @Output() onSearch: EventEmitter<any> = new EventEmitter(); @Input() itemTemplate: Function; @Input() multiple: boolean; constructor(private navController: NavController, private ionForm: Form, private platform: Platform, @Optional() private ionItem: Item) { } isNullOrWhiteSpace(value: any): boolean { if (value === null || value === undefined) { return true; } // Convert value to string in case if it's not. return value.toString().replace(/\s/g, '').length < 1; } ngOnInit() { this.isIos = this.platform.is('ios'); this.isMd = this.platform.is('android'); this.hasSearchEvent = this.onSearch.observers.length > 0; this.ionForm.register(this); if (this.ionItem) { this.ionItem.setElementClass('item-select-search', true); } } initFocus() { } @HostListener('click', ['$event']) _click(event: UIEvent) { if (event.detail === 0) { // Don't continue if the click event came from a form submit. return; } event.preventDefault(); event.stopPropagation(); this.open(); } select(selectedItem: any) { this.value = selectedItem; this.emitChange(); } emitChange() { this.propagateChange(this.value); this.onChange.emit({ component: this, value: this.value }); } emitSearch() { this.onSearch.emit({ component: this, text: this.filterText }); } open() { this.navController.push(SelectSearchPage, { selectComponent: this, navController: this.navController }); } reset() { this.setValue(null); this.emitChange(); } formatItem(value: any): string { if (this.itemTemplate) { return this.itemTemplate(value); } return value ? value[this.itemTextField] : null; } formatValue(): string { if (!this.value) { return null; } if (this.multiple) { return this.value.map(item => this.formatItem(item)).join(', '); } else { return this.formatItem(this.value); } } private propagateChange = (_: any) => { } writeValue(value: any) { this.setValue(value); } registerOnChange(fn: any): void { this.propagateChange = fn; } registerOnTouched(fn: any) { } setDisabledState(isDisabled: boolean) { } ngOnDestroy() { this.ionForm.deregister(this); } setValue(value: any) { this.value = value; // Get an item from the list for value. // We need this in case value contains only id, which is not sufficient for template rendering. if (this.value && !this.isNullOrWhiteSpace(this.value[this.itemValueField])) { let selectedItem = this.items.find(item => { return item[this.itemValueField] === this.value[this.itemValueField]; }); if (selectedItem) { this.value = selectedItem; } } } ngOnChanges(changes: SimpleChanges) { if (changes['items'] && this.items.length > 0) { this.setValue(this.value); } } } |
Što se komponente tiče gore navedene datoteke su sve što vam treba. Za nešto više posjetite https://github.com/eakoriakin/ionic-select-searchable
Kreiranje klase
Nakon što smo kreirali komponentu možemo kreirati i klasu koja će se nalaziti u posebnoj datoteci. Takva vrsta odvajanja olakšava kasnije održavanje aplikacija.
country.ts
|
1 2 3 4 5 |
export class Country { public id: number; public name: string; public population: number; } |
types.ts
|
1 |
export * from './country'; |
Struktura datoteka sada izgleda ovako
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
--src - app - assets - components - select-search - select-search-module.ts - select-search-page.html - select-search-page.scss - select-search-page.ts - select-search.html - select-search.scss - select-search.ts - pages - theme - types - country.ts - types.ts - ... |
Korištenje funkcionalnosti
Imamo komponentu, imamo klasu i sada napokon možemo nešto od svega toga konkretno i napraviti. Ako vam sve napravljeno do sada nije bilo poznato možete odahnuti jer se sada fokusiramo na home.ts i home.html datoteke jer ondje ćemo koristiti ranije kreiranu komponentu.
home.ts
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
import { Component } from '@angular/core'; import { FormBuilder, FormGroup, FormControl, Validators } from '@angular/forms'; import { SelectSearch } from '../../components/select-search/select-search'; import { Country } from '../../types/types'; @Component({ selector: 'page-home', templateUrl: 'home.html' }) export class HomePage { countries: Country[]; country1: Country; country2: Country; country3: Country; country4: Country; country5: Country; country6: Country; country7: Country; form: FormGroup; country8Control: FormControl; constructor(private _formBuilder: FormBuilder) { this.countries = this.getCountries(); this.country2 = this.countries[4]; this.country7 = this.countries[4]; this.country8Control = _formBuilder.control(this.countries[4], Validators.required); this.form = _formBuilder.group({ country8: this.country8Control }); } getCountries(): Country[] { return [ { id: 0, name: 'Afghanistan', population: 27657145 }, { id: 1, name: 'Albania', population: 2886026 }, { id: 2, name: 'Austria', population: 8725931 }, { id: 3, name: 'Bosnia and Herzegovina', population: 3531159 }, { id: 4, name: 'Croatia', population: 4190669 }, { id: 5, name: 'France', population: 66710000 }, { id: 6, name: 'Hungary', population: 9823000 }, { id: 7, name: 'Indonesia', population: 258705000 }, { id: 8, name: 'Liechtenstein', population: 37623 }, { id: 9, name: 'Mexico', population: 122273473 }, { id: 10, name: 'San Marino', population: 33005 } ]; } searchCountries(event: { component: SelectSearch, text: string }) { let text = (event.text || '').trim().toLowerCase(); if (!text) { event.component.items = []; return; } else if (event.text.length < 3) { return; } event.component.isSearching = true; // Simulate AJAX. setTimeout(() => { event.component.items = this.getCountries().filter(country => { return country.name.toLowerCase().indexOf(text) !== -1 }); event.component.isSearching = false; }, 2000); } countryTemplate(country: Country) { return `${country.name}, ${country.population}`; } countryChange(event: { component: SelectSearch, value: any }) { console.log('value:', event.value); } reset() { this.country8Control.reset(); } } |
home.html
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
<ion-header> <ion-navbar> <ion-title>Ionic: Select, search & autocomplete</ion-title> </ion-navbar> </ion-header> <ion-content> <ion-list> <ion-list-header> Simple Select </ion-list-header> <ion-item> <select-search [(ngModel)]="country1" title="Country" itemValueField="id" itemTextField="name" [items]="countries" (onChange)="countryChange($event)"> </select-search> </ion-item> </ion-list> <ion-list> <ion-list-header> With preselected value </ion-list-header> <ion-item> <select-search [(ngModel)]="country2" title="Country" itemValueField="id" itemTextField="name" [items]="countries" (onChange)="countryChange($event)"> </select-search> </ion-item> </ion-list> <ion-list> <ion-list-header> With Search </ion-list-header> <ion-item> <select-search [(ngModel)]="country3" title="Country" itemValueField="id" itemTextField="name" [items]="countries" [canSearch]="true" (onChange)="countryChange($event)"> </select-search> </ion-item> </ion-list> <ion-list> <ion-list-header> With Async Search (AJAX) </ion-list-header> <ion-item> <select-search [(ngModel)]="country4" title="Country" itemValueField="id" itemTextField="name" [items]="countries" [canSearch]="true" searchPlaceholder="..." (onSearch)="searchCountries($event)" (onChange)="countryChange($event)"> </select-search> </ion-item> </ion-list> <ion-list> <ion-list-header> With a custom template for items </ion-list-header> <ion-item> <select-search [(ngModel)]="country5" title="Country" itemValueField="id" itemTextField="name" [itemTemplate]="countryTemplate" [items]="countries" [canSearch]="true" (onChange)="countryChange($event)"> </select-search> </ion-item> </ion-list> <ion-list> <ion-list-header> Multiple selection </ion-list-header> <ion-item> <select-search [(ngModel)]="country6" title="Country" itemValueField="id" itemTextField="name" [items]="countries" [canSearch]="true" [multiple]="true" (onChange)="countryChange($event)"> </select-search> </ion-item> </ion-list> <ion-list> <ion-list-header> With "Clear" button </ion-list-header> <ion-item> <select-search [(ngModel)]="country7" title="Country" itemValueField="id" itemTextField="name" [items]="countries" (onChange)="countryChange($event)" [canReset]="true"> </select-search> </ion-item> </ion-list> <form [formGroup]="form"> <ion-list> <ion-list-header> Using together with Angular 2 Validators </ion-list-header> <ion-item> <select-search formControlName="country8" title="Country" itemValueField="id" itemTextField="name" [items]="countries" [canSearch]="true" (onChange)="countryChange($event)"> </select-search> <button ion-button item-right (click)="reset()" [disabled]="!form.valid">Reset</button> </ion-item> <ion-item> <p>Is valid: {{form.valid}}</p> </ion-item> </ion-list> </form> </ion-content> |
Na kraju to izgleda ovako
Prikaz podataka direktno s API-ja
Ovdje ću koristiti https://restcountries.eu/rest/v2/all API. Ovaj sam API koristio u jednom od prethodnih blog postova.
Prvo je potrebno kreirati ApiProvider naredbom:
|
1 |
$ ionic generate provider ApiProvider |
Sadržaj izgleda ovako:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
import { Injectable } from '@angular/core'; import { Http } from '@angular/http'; import 'rxjs/add/operator/map'; @Injectable() export class ApiProvider { constructor(public _http: Http) { console.log('Hello ApiProvider Provider'); } loadData(){ return this._http.get('https://restcountries.eu/rest/v2/all') .map(res => res.json()); } } |
I sada se opet vraćamo datotekama home.html i home.ts koje ću za potrebe ovog primjera pojednostaviti.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<ion-header> <ion-navbar> <ion-title>Ionic: Select, search & autocomplete</ion-title> </ion-navbar> </ion-header> <ion-content> <ion-list> <ion-list-header> Multiple selection </ion-list-header> <ion-item> <select-search [(ngModel)]="country" title="Country" itemValueField="population" itemTextField="name" [items]="countries" [canSearch]="true" [multiple]="true" (onChange)="countryChange($event)"> </select-search> </ion-item> </ion-list> </ion-content> |
Funkcionalnost se sastoji od tri glavna dijela. Prvi dohvaća sve podatke s API-ja, drugi puni novi niz samo sa podacima koje želimo koristiti u aplikaciji i treći se tiče odabira vrijednosti u komponenti na klijentskoj strani.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
import { Component } from '@angular/core'; import { SelectSearch } from '../../components/select-search/select-search'; import { Country } from '../../types/types'; import { ApiProvider } from "../../providers/api/api"; @Component({ selector: 'page-home', templateUrl: 'home.html', providers: [ApiProvider] }) export class HomePage { countries: Country[]; country: Country; countryOptions:any; constructor(public _apiProvider: ApiProvider) { } ionViewDidLoad() { this.getCountries(); } getCountries(){ this._apiProvider.loadData().subscribe(res => { this.countryOptions = res; console.log(this.countryOptions); let myCountries = []; if(this.countryOptions.length > 0) { for(let i = 0; i < this.countryOptions.length; i++) { myCountries.push({ id: this.countryOptions[i].alpha2Code, population: this.countryOptions[i].population, name: this.countryOptions[i].name }); } } this.countries = this.passingFunction(myCountries); }); } passingFunction(data:any): Country[]{ return data } countryChange(event: { component: SelectSearch, value: any }) { console.log('value:', event.value); let myCountries = []; if(event.value.length > 0) { for(let i = 0; i < event.value.length; i++) { myCountries.push({ id: event.value[i].id }); } } console.log(myCountries); } } |
Funkcija this.getCountries(); dohvaća popis svih država s API-ja. Unutar te funkcije vrtimo petlju kojom odabiremo koje parametre trebamo od API-ja jer ne trebaju nam svi parametri. Znači uzimao samo id, population i name.
|
1 2 3 4 5 6 7 8 9 |
if(this.countryOptions.length > 0) { for(let i = 0; i < this.countryOptions.length; i++) { myCountries.push({ id: this.countryOptions[i].alpha2Code, population: this.countryOptions[i].population, name: this.countryOptions[i].name }); } } |
Tako napunjen niz (array) proslijedimo ranije kreiranoj komponenti this.countries = this.passingFunction(myCountries);.
I na kraju kada odaberemo željene vrijednosti opet vrtimo petlju izdvajajući samo id.
|
1 2 3 4 5 6 7 8 |
let myCountries = []; if(event.value.length > 0) { for(let i = 0; i < event.value.length; i++) { myCountries.push({ id: event.value[i].id }); } } |
Na kraju to izgleda ovako:
Zaključak
I to je sve. Ova se tema može obraditi na više načina, ali vjerujem da je i ovo dovoljno da dobijete uvid u jedan od načina kako riješiti pitanje Ionic autocomplete funkcionalnosti.

