반응형

모듈 기본 세팅값

// module.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';

@NgModule({
  imports: [
    IonicModule,
    CommonModule,
    FormsModule,
    ReactiveFormsModule
  ]
  ...

위와같은 환경?을 구축해 두셔야 합니다.


<!-- HTML -->
<form [formGroup]="optionForm" (ngSubmit)="submitForm()">

  <ion-item lines="full">
    <ion-label position="floating">날짜</ion-label>
    <ion-datetime formControlName="workDate" min="2020-02-11" displayFormat="YYYY-MM-DD"></ion-datetime>
  </ion-item>
  
  <ion-button type="submit" color="danger" expand="block" [disabled]="!optionForm.valid">설정하기</ion-button>  
  
</form>

기본적으로 <form>, <ion-input>, <ion-button> 이렇게 3개로 구성됩니다.

 

// ts.file

import { Component, OnInit } from '@angular/core';
import { Validators, FormGroup, FormBuilder } from '@angular/forms';

@Component({
  selector: ... 생략
})
export class ... {

  optionForm: FormGroup;

  constructor(public formBuilder: FormBuilder) { }

  ngOnInit() {
    this.optionForm = this.formBuilder.group({
      workDate: [new Date().toISOString(), [Validators.required]]
    })
  }
  
  submitForm() {
    console.log(this.optionForm.value)
  }
}

onInit할때, form을 설정합니다. (Validator 및 초기값을 추가할 수 있습니다.)

 

submit 버튼에 [disabled]="!optionForm.valid"를 이용하여 모든 form구릅 안에 있는 Validation이 통과해야만 클릭할 수 있도록

할 수 있습니다.


결과화면(입력전)
결과화면(입력후)

 

반응형

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

ion-input 안드로이드 작동  (0) 2021.06.07
Ionic 어플 - 아이폰 앱 설치(배포)  (0) 2021.05.04
Ionic 4 배포하기  (0) 2019.11.08
Ionic 4 searchbar 자동완성  (0) 2019.10.24
DataHandling  (0) 2019.10.18
반응형

환경 - 맥, Ionic4, angular

 

아래 3개의 명령어를 실행하세요. - angular cli가 글로벌(-g)로 설치되어 있어야 합니다.

ng build --prod  

ionic capacitor sync android 

ionic capacitor sync ios

capacitor.config.json

appId: 앱스토에서 사용될 Id 

더보기

android studio에서 열기 : ionic capacitor open android 

x-code에서 열기 : ionic capacitor open ios

Android 세팅

<!-- android/app/src/main/res/values/strings.xml app_name -->

<!-- 앱아이디 = capacitor.config.json의appId -->

<string name="app_name">PairBnB</string>
<string name="title_activity_main">PairBnB</string>
<string name="package_name">앱아이디</string>
<string name="fileprovider_authority">앱아이디</string>
<string name="custom_url_scheme">앱아이디</string>
<!-- android/app/src/main/AndroidManifest.xml -->

<!-- 앱아이디 = capacitor.config.json의appId -->

<manifest xmlns:android="..." package="앱아이디"> ... </manifest>

 

// android/app/src/build.gradle

// 앱아이디 = capacitor.config.json의appId

defaultConfig {
	applicationId "앱아이디"	
}

//versionCode, versionName을 통해서 버전을 변경할 수 있습니다.

 

퍼미션은 AndroidManifest 에서 uses-permission 테그에서 확인 할 수 있습니다.

 

iOS세팅

<!-- ios/App/App/Info.plist -->

<key>CFBundleDisplayName</key>
  <string>PairBnB</string>

X-code에서 App을 열면 오른쪽화면에서 Version을 변경할 수 있습니다.

 

아이콘 변경

 

Image Gorilla(아이콘 다양한 크기 제공)는 구글에서 쉽게 접근할 수 있습니다.

 

ios

App/App/Assets.xCss 에서 아이콘을 드래그 엔 드랍으로 변경합니다.

 

Android

App/res를 마우스 오른쪽 후 new Image Assets을 누릅니다. 다운받은 Icon Png File을 서택합니다.

 

splashscreen을 Image Gorilla를 통해 다운받습니다.

App/res/drawable-land.../splash.png를 변경해 줍니다.

 

Android Deploy

안드로이드 스튜디오 에서 

Build->Generate Signed Bundle/APK -> next

key store path : 나의 저장소

password : 마음대로

 

next를 하다보면 buildType이 나옵니다. 반드시 release로 해야합니다.

 

iOS Deploy - 유료계정이 없네요 ㅠㅠ

 

Web - progressive web app Deploy

www폴더가 배포할 수 있는 폴더입니다.

 

하지만 PWA로 진행해보겠습니다.

아래 2개를 명령어를 실행합니다.

 

ng add @angular/pwa

ng build --prod

 

filrebase를 이용하는 경우에 다음과 같이 실행합니다.

fireabse init

?  What do you want to use as your public directory? www
? Configure as a single-page app (rewrite all urls to /index.html)? Yes
? File www/index.html already exists. Overwrite? 마음것 하세용~

 

www/ngsw-config.json에 있느 설정값으로 deploy됩니다.

 

다음 명령어를 실행합니다.

firebase deploy

 

 

 

반응형

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

Ionic 어플 - 아이폰 앱 설치(배포)  (0) 2021.05.04
아이오닉 form handling  (0) 2020.02.14
Ionic 4 searchbar 자동완성  (0) 2019.10.24
DataHandling  (0) 2019.10.18
State 관리  (0) 2019.10.12
반응형

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
반응형

Http

1. HttpClient 사용

1.1. HttpClientModule을 App.module.ts import

// file.ts

@NgModule({
  declarations: [AppComponent],
  imports: [HttpClientModule, IonicModule.forRoot(), AppRoutingModule],
  ...

1.2. httpClient사용하면서 알게된 점.

// file.ts

http.get('URL').forEach(...)

return http.get('URL').pipe(...)  // 어디선가 subscribe()가 있어야만 실행됨.

httpClinet.http.get 앞에 반드시 return해주어야 subscribe 할 수 있습니다.

 

Subjection

 

2. BehaviorSubject<T[]>([]) 사용

 

2.1. _array에 값 할당하기

// file.ts

private _array = new BehaviorSubject<T[]>([]);

method() {
const _temp: T[] = [];
 ...
 this._array.next(_temp);
}

Json

get의 타입지정시 1

interface Person {
	name: string,
    age: number
}

// http.get<Person[]>(...)
// http.get<{[name: string, age:number]}>(...)

// file.json
[{
    "name": "hello",
    "age": 20
  },
 {
    "name": "world",
    "age": 22
  }
]

get의 타입지정시 2

// json data

interface Person {
	name: string,
    age: number
}

// http.get<[poeple: string]: Person[]>(...)
// http.get<{[people: string]: [{name: string, age: number}]}>(...)

{
  "people":[
    {
      "name": "hello",
      "age": 20
    },
    {
      "name": "world",
      "age": 22
    }
  ]
}

 

반응형

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

Ionic 4 배포하기  (0) 2019.11.08
Ionic 4 searchbar 자동완성  (0) 2019.10.24
State 관리  (0) 2019.10.12
Styling & Theming  (0) 2019.10.12
유용한 컴포넌트 소개  (0) 2019.10.12
반응형

State : 

UI State spinner의 작동 시기 및 Loading 데이터.
Temporary / Local State Service의 List와 같은 데이터.
Persistent State Storage 혹은 Database와 같은 자료

 

RxJS의 Subject를 이용한 UI State 관리

Http로 데이터를 로딩하는 동안 Spinner를 작동하는 예제로 설명하겠습니다.

 

Http - Async Data를 로딩 합니다. (delay를 사용했습니다.)

최신의 데이터를 받아서 UI의 랜더링을 할 수 있도록 State를 관리합니다.

 

  //service.ts
  
  import { BehaviorSubject } from 'rxjs';
    // BehaviorSubject<제네릭>(초기값)으로 Subject로 객체를 주입합니다.
  private _places = new BehaviorSubject<Place[]> ([
    new Place(), new Place()
  ]);

    // Observable로 리스트를 보냅니다. 가장 최신의 async값을 보내기 위함입니다.
  get places() {
    return this._places.asObservable();
  }
  
  import { take, tap, delay } from 'rxjs/operators';
  /* Observable을 반환 하는 take, delay, tap  operator입니다.
     tap: 
     탭은 3가지의 경우에 쓰일 수 있습니다.
     nextOrObserver: Observable이 실행 될 경우.
     error: 에러가 발생한 경우.
     complete: 완료된 경우.
  */ 
  addPlace() {
    const newPlace = new Place(); //Place를 생성하는 값들을 제거한 버전입니다.
      // pipe operator들을 연속해서 사용할 수 있도록 합니다.
    return this.places.pipe(
        //가장 최근의 값만 가져와 처리합니다.
      take(1), 
        //Http의 로딩을 해야하지만, 코드가 길어지므로 대체. 시간을 1초로 합니다.
      delay(1000), 
        //해당 매쏘드에서 consume하지 않고 return합니다.
      tap(places => {
          // BehaviorSubject.next() 실행할 작업을 기입합니다.
        this._places.next(places.concat(newPlace)); // 해당 리스트에 newPlace를 추가합니다.
      })
    );
  }
// page.ts

  isLoading = false;

  import { LoadingController } from '@ionic/angular';
    // 로딩시 spinner를 작동할 수 있도록 LoadingContorller 사용.
  constructor(private loadingCtrl: LoadingController) {}
  
  onCreateOffer() {
    this.loadingCtrl
      .create({
        message: 'Creating place...' // 스피너와 함께 나올 문구
      })
      .then(loadingEl => {
        loadingEl.present(); // 스피너를 UI에 표시.
        this.placesService
            // 위에서 구현한 매쏘드
          .addPlace()
            // next()를 구독(subscribe)
          .subscribe(() => { 
            loadingEl.dismiss(); // UI에서 스피너 제거.
          });
      });
  }
  

 

번외.

ionic의 lifeCycle을 관리해주어야 합니다.

ngOnInit() 의 경우 angular가 관리를 해주지만, Subject는 사용자가

ngOnDestroy()를 해주어야 합니다.

//page.ts

import { Subscription } from 'rxjs';
  // Subscription을 주입합니다.
private placeSub: Subscription;

  매쏘드() {
    this.placeSub = this.placesService
        .addPlace()
        .subscribe(
          ... // 여러 작업 수행
        });
    });
  }
  
  ngOnDestroy() {
    if (this.placeSub) {
      this.placeSub.unsubscribe();
    }
  }
반응형

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

Ionic 4 searchbar 자동완성  (0) 2019.10.24
DataHandling  (0) 2019.10.18
Styling & Theming  (0) 2019.10.12
유용한 컴포넌트 소개  (0) 2019.10.12
캐패시터로 네이티브 앱 만들기  (0) 2019.09.25
반응형

속성값 변경

Css 속성값은 :root 선택자를 이용해 앱 전체에 적용할 수 있습니다.

src/theme/variables.scss

에 위치한 것으로 전반적인 색상을 변화시킬 수 있습니다.

/* 모든 모드의 값을 설정합니다. */
:root {
  /* 앱 전반적인 배경색을 설정합니다. */
  --ion-background-color: #ff3700;

  /* 앱 전반적인 폰트를 설정합니다. */
  --ion-font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "Roboto", sans-serif;
}

/* iOS 앱에 대한 텍스트 색상을 설정합니다. */
.ios {
  --ion-text-color: #000;
}

/* 매테리얼 디자인의 텍스트 색상을 설정합니다. */
.md {
  --ion-text-color: #222;
}

.md, .ios, :root와 같은 값이 글로벌 선택자 입니다.

 

컴포넌트

/* ion-button의 색을 설정합니다. */
ion-button {
  --color: #222;
}

/*  ion-button의 .fancy-button 클라스에 대한 배경색을 설정합니다. */
.fancy-button {
  --background: #00ff00;
}

 

앱 전체의 색 변경

아이오닉에서 전체 색상을 변경할 수 있는 Color Generator를 제공하고 있습니다.

primary와 같은 색상을 변경함으로, 앱의 특징이나 아이덴티티를 갖을 수 있도록 도와줍니다.

 

반응형

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

DataHandling  (0) 2019.10.18
State 관리  (0) 2019.10.12
유용한 컴포넌트 소개  (0) 2019.10.12
캐패시터로 네이티브 앱 만들기  (0) 2019.09.25
Ionic Component Basics  (0) 2019.09.18
반응형

아이오닉 컴퍼넌트의 간단한 소개와 사용법 입니다. 사이트

 

UI Components - Ionic Documentation

Ionic is the app platform for web developers. Build amazing mobile, web, and desktop apps all with one shared code base and open web standards

ionicframework.com

 

<ion-lable>

텍스트를 스타일링해 주는 <H1>, <p> 테그와 사용하면 더욱 좋은 스타일링과 이팩트를 줄 수 있습니다.

위와 같이 <ion-input> 태그와 함께 사용합니다.

<ion-label position="floationg">
  <h1> ... </h1>
</ion-label>


<ion-item>
  <ion-label>
    <ion-input>...</ion-input>
  </ion-label>
<ion-item>

 

<ion-text>

text만 스타일링 할 경우 사용합니다.

 

<ion-item-sliding> - Swipable List Item

왼쪽 오른쪽으로 밀어서 작동합니다.

<ion-list>
  <ion-item-sliding *ngFor="let item of items" #slidingItem>
    <ion-item-options side="start" >
        <ion-item-option
          color="secondary"
          (click)="onEdit(item.id, slidingItem)"
        >
          <ion-icon name="create" slot="icon-only"></ion-icon>
        </ion-item-option>
      </ion-item-options>
    <ion-item
      [routerLink]="['클릭시 이동할 주소']"
    >
      <ion-thumbnail slot="start">
        <ion-img [src]="item.imageUrl"></ion-img>
      </ion-thumbnail>
      <ion-label>
        <h1>{{ item.title }}</h1>
      </ion-label>
    </ion-item>
    <ion-item-options side="end">
      <ion-item-option
        color="danger"
        (click)="onCancel(item.id, slidingItem)"
      >
        <ion-icon name="trash" slot="icon-only"></ion-icon>
      </ion-item-option>
    </ion-item-options>
  </ion-item-sliding>
</ion-list>

스타일링을 위해 ion-icon등을 사용했지만.

기본 틀은 아래와 같습니다.

<ion-list>
  <!-- Sliding item with text options on both sides -->
  <ion-item-sliding>
    <ion-item-options side="start">
      <ion-item-option (click)="favorite(item)">Favorite</ion-item-option>
      <ion-item-option color="danger" (click)="share(item)">Share</ion-item-option>
    </ion-item-options>

    <ion-item>
      <ion-label>Item Options</ion-label>
    </ion-item>

    <ion-item-options side="end">
      <ion-item-option (click)="unread(item)">Unread</ion-item-option>
    </ion-item-options>
  </ion-item-sliding>
</ion-list>

<ion-item-option>을 이용하여 사용하게 됩니다.

<ion-item-options side="strart">와 같이 side의 값으로 위치를 결정됩니다.

side의 값에 따라: start는 왼쪽, end는 오른쪽에 위치하게 됩니다.

 

<ion-virtual-scroll>

화면에 보이는 곳만 리스트를 보여줍니다.

성능의 최적화를 위해 사용하며, 50개 이상일 경우 이득이 있습니다.

<ion-content>
  <ion-virtual-scroll [items]="items" approxItemHeight="320px">
    <ion-card *virtualItem="let item; let itemBounds = bounds;">
      <div>
        <ion-img [src]="item.imgSrc" [height]="item.imgHeight" [alt]="item.name"></ion-img>
      </div>
    <ion-card-header>
      <ion-card-title>{{ item.name }}</ion-card-title>
    </ion-card-header>
    <ion-card-content>{{ item.content }}</ion-card-content>
    </ion-card>
  </ion-virtual-scroll>
</ion-content>

 

위와 같이 사용하며, <ion-list>대신 <ion-virtual-scroll>를 사용해야 합니다.

또한 *ngFor대신 [items]="구릅대상" 으로 진행합니다.

 <ion-virtual-scroll [items]="items" approxItemHeight="320px">
    <ion-card *virtualItem="let item; let itemBounds = bounds;">

 

이미지 Element 추가하기

Lazy 로딩이기 때문에, <ion-img>는 래핑을 필요합니다.

<ion-thumbnail> 혹은 <ion-avartar>를 사용하길 추천합니다.

 

<ion-segment> 

tab은 각 페이지를 이동시 사용하는 대신, segment는 버튼으로 필터등의 용도로 사용됩니다.

<ion-segment (ionChange)="segmentChanged($event)">
  <ion-segment-button value="friends">
    <ion-label>Friends</ion-label>
  </ion-segment-button>
  <ion-segment-button value="enemies">
    <ion-label>Enemies</ion-label>
  </ion-segment-button>
</ion-segment>

 

버튼의 작동은, 이벤트를 전송하는 방식으로 합니다.

//file.ts

segmentChanged(event: CustomEvent<SegmentChangeEventDetails>) {
  ...
}

<ion-spinner>

<!-- Default Spinner -->
<ion-spinner></ion-spinner>

<!-- Lines -->
<ion-spinner name="lines"></ion-spinner>

<!-- Lines Small -->
<ion-spinner name="lines-small"></ion-spinner>

<!-- Dots -->
<ion-spinner name="dots"></ion-spinner>

<!-- Bubbles -->
<ion-spinner name="bubbles"></ion-spinner>

<!-- Circles -->
<ion-spinner name="circles"></ion-spinner>

<!-- Crescent -->
<ion-spinner name="crescent"></ion-spinner>

<!-- Paused Default Spinner -->
<ion-spinner paused></ion-spinner>

 

위와같이 쉽게 이용할 수 있습니다.

다만 ts로 스피너가 작동할 시간을 정해야 합니다.

// file.ts
// LodingController를 import해서 사용합니다.

constructor(loadingCtrl: LoadingController) {}

  openSpinner() {
    this.loadingCtrl({keyboardClose:true, message:"..."})
      .then(loadingEl => {
        loadingEl.present();
        shomeMethod().subscribe(() => {
          loadingEl.dismiss();
        })
    })
  }

LoadingController를 import해서 사용해야 합니다.

loadingEl의 present()와 dismiss()로 시작과 종료를 명시해주어야 합니다.

 

<ion-action-sheet>

"Show Action Sheet" 버튼을 누르면 아래에서 창이 나타나는 기능입니다.

import { Component } from '@angular/core';
import { ActionSheetController } from '@ionic/angular';

@Component({
  selector: 'action-sheet-example',
  templateUrl: 'action-sheet-example.html',
  styleUrls: ['./action-sheet-example.css'],
})
export class ActionSheetExample {

  constructor(public actionSheetController: ActionSheetController) {}

  async presentActionSheet() {
    const actionSheet = await this.actionSheetController.create({
      header: 'Albums',
      buttons: [{
        text: 'Delete',
        role: 'destructive',
        icon: 'trash',
        handler: () => {
          console.log('Delete clicked');
        }
      }, {
        text: 'Share',
        icon: 'share',
        handler: () => {
          console.log('Share clicked');
        }
      }, {
        text: 'Play (open modal)',
        icon: 'arrow-dropright-circle',
        handler: () => {
          console.log('Play clicked');
        }
      }, {
        text: 'Favorite',
        icon: 'heart',
        handler: () => {
          console.log('Favorite clicked');
        }
      }, {
        text: 'Cancel',
        icon: 'close',
        role: 'cancel',
        handler: () => {
          console.log('Cancel clicked');
        }
      }]
    });
    await actionSheet.present();
  }

}

create매쏘드를 이용해서 각 버튼의 넥스트와 기능을 명시해주어야 합니다.

ActionSheetController라는 컨트롤러를 import해서 사용합니다.

반응형

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

State 관리  (0) 2019.10.12
Styling & Theming  (0) 2019.10.12
캐패시터로 네이티브 앱 만들기  (0) 2019.09.25
Ionic Component Basics  (0) 2019.09.18
아이오닉 튜토리얼  (0) 2018.06.03
반응형

ANDROID

https://ionicframework.com/docs/building/android

 

Android Development - Ionic Documentation

Ionic is the app platform for web developers. Build amazing mobile, web, and desktop apps all with one shared code base and open web standards

ionicframework.com

안드로이드 스튜디오를 설치해야 합니다.

https://capacitor.ionicframework.com/docs/getting-started/dependencies#android-development

 

Capacitor Required Dependencies - Capacitor

Capacitor Required Dependencies Capacitor has a number of dependencies depending on which platforms you're targeting and which operating systems you are developing on. The base requirements are Node v8.6.0 or later, and NPM version 5.6.0 or later (which is

capacitor.ionicframework.com

Java8 JDK는 반드시 설치되어야 하며, API level 21또는 그이상을 타겟팅해야합니다.

즉, Angroid 5.0(Lollipop)이나 그 이상입니다.

안드로이드 스튜디오의 설치가 완료 되었다면, SDK 매니저로 들어가 확인합니다.

또한 SDK Tools탭에서는, Android SDK Build-Tools설치여부를 확인하고,

Android SDK Tools의 버전을 확인합니다.

Intel x86 Emulator Accelerator (HAXM installer), Android Emulator의 설치여부를 확인하기 바랍니다.


설치가 완료되었다면, 터미널에서 캐패시터를 이용해 안드로이드를 추가해 보겠습니다.

ionic capacitor add android

다음과 같은 에러가 발생한다면,

[error] Capacitor could not find the web assets directory "/Users/aw/dev/ionic/udemy/section5/ng-ionic-05-finished/www".

기존에 빌딩한 이력이 없기 때문에, ng build명령어를 실행합니다.

ng build

설치가 완료 되었다면, www폴더가 생성됩니다. 다시한번 ionic capacitor add android 명령을 입력합니다.

ionic capacitor add android

appID를 변경합니다.

// capacitor.config.json

{
  "appId": "com.what.you.want",
  "appName": "ionic-angular-course",
  "bundledWebRuntime": false,
  "npmClient": "npm",
  "webDir": "www"
}

아이디에는 -를 넣지 않도록합니다.

 

아이디가 변경되었으므로, www폴더에 있는걸 android폴더로 복사해줍니다.

ionic capacitor copy android

이제 실행해 보겠습니다.

ionic capacitor run android

전부 실행이 되면, 자동으로 안드로이드 스튜디오가 열립니다.

AVD Manager를 열어 기기를 만듭니다.

생성이 되었다면, 오른쪽에 초록색 실행(재생) 아이콘을 눌러서 실행합니다.


부팅이 완료 되었다면, 초록색 실행 버튼을 눌러 실행합니다.

 

ionic capacitor run android -l

 

을 이용하면 실시간으로 업데이트 되는 기능을 제공합니다.

위 커맨드를 이용할 시 앱을 재실행 해주시기 바랍니다.


실재 안드로이드 폰에서 실행하기.

USB로 안드로이드 폰과 연결후, "Developer Options"를 설정합니다. 

자세한 내용 참조: https://developer.android.com/studio/debug/dev-options

"Developer Otions"에서 "USB Debugging"를 체크하됩니다.

 


IOS

Xcode, Xcode-tool이 설치되어 있어야합니다. 물론, 클라우드도 지원하지만, 유료입니다.

혹은 맥을 갖고 있어야 합니다.

 

안드로이드와 동일하게 실행합니다.

ionic capacitor add ios

ng build

ionic capacitor run ios

자동으로 Xcode가 실행됩니다.

signing에서 반드시 팀을 선택해주어야 합니다.

없다면, 계정을 추가해야합니다.

개발만 한다면, 유료로 등록하지 않아도 됩니다.

스토어에 올릴 때에만 금액을 지불하게 되어있습니다.

 

ionic capacitor run ios -l

동일하게 가능합니다.

반응형

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

State 관리  (0) 2019.10.12
Styling & Theming  (0) 2019.10.12
유용한 컴포넌트 소개  (0) 2019.10.12
Ionic Component Basics  (0) 2019.09.18
아이오닉 튜토리얼  (0) 2018.06.03
반응형

핵심 어플리케이션 빌딩 블럭

UI Components: <icon-card>, <ion-image> ... 

Temes & Styles: CSS & CSS Cariables

Navigation: Custom or Built-in Router

State Management: Passing Data Around

Native Device Features: Camera & More

Ionic CLI & Publishing: From Develmopment to Deplyment


아이오닉 컴포넌트 구조

<ion-button fill="outline" color="primary">

<ion-button>: HTML Element와 동일하게 사용가능합니다.

fill="outlet": Attribute와 Properties도 동일합니다.

event Emit도 가능합니다.

HTML: 코드를 계속 들어가다보면 평범한 HTML를 wrap한것을 알 수 있습니다.

CSS의 var을 통해서 테마를 쉽게 적용할 수 있도록 합니다.

JavaScript: 작동 코드가 있습니다.

 

Stencil을 알고 있다면 유리한 부분이 많습니다.

https://github.com/ionic-team/ionic/blob/master/core/src/components/button/button.tsx

button Component가 어떻게 작동 하는지 알 수 있습니다.


앵귤러 없는 Ionic 프로젝트 세팅

index.html 만 만들고,

html:5로 스켈레톤(더미)를 만듭니다.

<html>
...
  <script type="module" src="https://cdn.jsdelivr.net/npm/@ionic/core@4.7.4/dist/ionic/ionic.esm.js"></script>
  <script nomodule src="https://cdn.jsdelivr.net/npm/@ionic/core@4.7.4/dist/ionic/ionic.js"></script>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ionic/core@4.7.4/css/ionic.bundle.css"/>
</head>
<body>
</body>
</html>

https://ionicframework.com/docs/installation/cdn

아이오닉프레임.com -> Guide -> Packages & CDN의 HTML을 복붙합니다.

 

이제 아이오닉 컴포넌츠를 사용할 수 있습니다.


아이오닉 컴포넌트 학습하는 곳

https://ionicframework.com/docs/components

위 사이트에서 마음에 드는 컴포넌트를 사용할 수 있습니다.

<ion-button>를 예를 들면,

어떻게 쓰는지 configure나와있고, 

HTML에서 사용할 수 있는 값들: Fill, Size와 같은 의 값에 대한 정보를 얻을 수 있습니다.

Usage를 보면, 어떻게 코드를 입력해야 되는지 나옵니다.

또한 Prorperties에서 여러 속성을 사용할 수 있도록 돕습니다.

Events 및 CSS를 오버라이드 할 수 있는지에 대한 정보까지 얻을 수 있습니다.


아이오닉 기본 Component 사용하기

- 도큐먼트사용하는 방법 입니다.

예산 플래너를 만들어 보겠습니다.

모바일 처럼 보이는 것을 만들어 보겠습니다.

 

body에 <ion-app>을 찾아 입력합니다. 루트 컴포넌트 입니다.

<ion-content>를 이용하여 main 어플리케이션 콤턴트를 레핑합니다.

스크롤링을 컴트롤하고, 디스플레이를 도와줍니다.

toolbar를 추가해보겠습니다.

<ion-header>가 있을 경우, 콘텐트의 top에 고정되어 나타나게 되는등 의 설명까지 나와있습니다.

사용하기 위해선 ion-title을 사용해야하는군요?

<ion-title>에 가서 usage를 보도록 하겠습니다.

아래의 코드처럼 되겠죠?

...
<body>
  <ion-app>
    <ion-header>
      <ion-toolbar> //Usage를 복붙합니다.
        <ion-title>Budget Planner</ion-title>
      </ion-toolbar>
    </ion-header>
  </ion-app>
</body>
</html>

크롬으로 dev툴을 열어 mobile 미리 보기로 시뮬레이션 할 수 있습니다.

또한 Elements를 보면, DOM으로 만들어 진 것을 볼 수 있습니다.

 

<ion-toolbar color="primary">로 색상을 추가할 경우,

<ion-title>의 글자색이 흰색으로 자동변경 됩니다. 엄청 좋은 편리한 기능입니다.

...
<body>
  <ion-app>
    <ion-header>
      <ion-toolbar color="primary">
        <ion-title>Budget Planner</ion-title>
      </ion-toolbar>
    </ion-header>
  </ion-app>
</body>
</html>

 


More Baisc Components

input를 사용해 보겠습니다.

다큐먼트를 보고 위에서 했던것처럼 진행합니다.

...
<body>
  <ion-app>
    <ion-header>
      <ion-toolbar color="primary">
        <ion-title>Budget Planner</ion-title>
      </ion-toolbar>
    </ion-header>
    <ion-content>
      <ion-item>
        <ion-label position="floating">Expense Reason</ion-label>
        <ion-input type="text"></ion-input>
      </ion-item>
    </ion-content>
  </ion-app>
</body>
</html>

허전해 보입니다. 한개를 더 추가하고, 요즘 많이 사용하는 <ion-card>를 추가해보겠습니다.

...
<body>
  <ion-app>
    <ion-header>
      <ion-toolbar color="primary">
        <ion-title>Budget Planner</ion-title>
      </ion-toolbar>
    </ion-header>
    <ion-content>
      <ion-card>
        <ion-card-header>
          <ion-card-title>new Expense</ion-card-title>
        </ion-card-header>
        <ion-card-content>
          <ion-item>
            <ion-label position="floating">Expense Reason</ion-label>
            <ion-input type="text"></ion-input>
          </ion-item>
          <ion-item>
            <ion-label position="floating">Expense Amount</ion-label>
            <ion-input type="number"></ion-input>
          </ion-item>
        </ion-card-content>
      </ion-card>
    </ion-content>
  </ion-app>
</body>
</html>

조금 보기 좋아졌죠?


Component Categories

공식적인 것은 아니지만, (강의에서)개인적으로 생각하는 분류입니다.

Output - 유저에게 보여주고 싶은 것들은 모아보았습니다.

Layout - 구조적인 면을 나타냅니다. 주로 구릅핑과 정렬시 사용됩니다.

Input - 유저의 입력 값을 받을 경우 사용하면 좋은것들 입니다.


Ionic Grid 예제

<ion-grid>
  <ion-row>
  	<ion-col size-md="6">
       ... <!-- <ion-card> -->
    </ion-col>
  </ion-row>
</ion-grid>

다큐먼트를 참고하여 size-xs,sm,md,lg의 각 크기에 따라 적용되는 것을 학습해야 올바른 사용이 가능합니다.

size는 1-12까지 가능합니다. 위처럼 size-md="6"로 할 경우, 작은 화면에서는 꽉 차고, 큰 화면에서 반만 차지하게 됩니다.


아이콘 추가 & Slots 사용

https://ionicons.com/

 

Ionicons: The premium icon pack for Ionic Framework

Ionicons is an open-sourced and MIT licensed icon pack.

ionicons.com

아이콘 사이트에서 원하는 아이콘을 찾아 추가하도록 하겠습니다.

<ion-button fill="outline" color="danger" id="btn-cancel">
  <ion-icon slot="start" name="close"></ion-icon
  >Clear</ion-button
>

slot의 경우, 값에 따라 아이콘의 위치가 바뀝니다. 위 코드의 경우, 버튼 내 글자와 아이콘 사이의 거리가 달라집니다.

보시는 바와 같이 왼쪽으로 버튼이 몰려있습니다. CSS를 이용하여 버튼의 위치를 변경해 보겠습니다.


CSS Utility 속성 사용하기

https://ionicframework.com/docs/layout/css-utilities

 

CSS Utilities - Ionic Documentation

Ionic is the app platform for web developers. Build amazing mobile, web, and desktop apps all with one shared code base and open web standards

ionicframework.com

Utility 다큐먼트에 있는 속성을 사용해보겠습니다.

<div margin-vertical text-right>
  <ion-button fill="outline" color="danger" id="btn-cancel">
  	<ion-icon slot="start" name="close"></ion-icon
	>Clear</ion-button
  >
  <ion-button id="btn-confirm">
    <ion-icon slot="start" name="add"></ion-icon>
    Add Expense
  </ion-button>
</div>

margin-vertical,과 text-right를 사용했습니다.

HTML에서 CSS처럼 익숙하게 작동합니다.

오른쪽으로 이동한 것을 알 수 있습니다.


Ionic Element를 "기존"HTML Element처럼 쓰기

버튼 클릭과 같은 로직을 추가해 보겠습니다. 

바닐라.js를 이용하여 작동하는 것이기 때문에, 다른 프레임웍(Angular, Vue, React)에 쉽게 붙일 수 있습니다.

 

</body> HTML 본문이 끝나기 바로 직전에 script 태그를 추가합니다.

<!-- index.html -->
...
<script src="app.js"></script>
</body>

그리고 HTML에 id를 넣어줍니다.

<!-- index.html -->
<ion-button id="btn-confirm">
  <ion-icon slot="start" name="add"></ion-icon>
  Add Expense
</ion-button>

해당 아이디를 선택하여 클릭 이벤트를 추가합니다.

//app.js
const confirmBtn = document.querySelector('#btn-confirm');

confirmBtn.addEventListener('click', () => {
  console.log('It's works');
})

아이오닉 Elements 코딩

기본으로 제공되는 DOM api아이오닉에서 제공하는 기능<ion-list>을 사용해보겠습니다.

ion-list는 아이오닉에서 제공하는 것으로, 동적으로 리스트를 디스플레이해줍니다.

<!-- index.html -->
<ion-row>
  <ion-col size-md="6" offset-md="3">
    <ion-list id="expenses-list"></ion-list>
  </ion-col>
</ion-row>
// app.js

const expensesList = document.querySelector('#expenses-list');

const newItem = document.createElement('ion-item');
newItem.textContent = enteredReason + ': $' + enteredAmount;

expensesList.appendChild(newItem);

ion-item을 을 생성 및 입력 값을 DOM에 추가하는 코드입니다.


컨트롤러 컨포넌트 사용하기!

https://ionicframework.com/docs/api/alert

 

ion-alert - Ionic Documentation

Ionic is the app platform for web developers. Build amazing mobile, web, and desktop apps all with one shared code base and open web standards

ionicframework.com

컴퍼넌트 다큐멘테이션을 이용하겠습니다.

<!-- index.html -->
...
<ion-alert-controller></ion-alert-controller>
</ion-app>
...

아이온에서 제공하는 ion-alert-controller 태그를 사용합니다.

// app.js

const alertCtrl = document.querySelector('ion-alert-controller');
alertCtrl
  .create({
    message: 'Please enter valid reason and amount!',
    header: 'Invalid inputs',
    buttons: ['Okay']
  })
  .then(alertElement => {
    alertElement.present();
});

 

create는 observable을 반환합니다.

.then을 이용하여 element의 present() 매쏘드로 디스플레이 할 수 있습니다.

반응형

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

State 관리  (0) 2019.10.12
Styling & Theming  (0) 2019.10.12
유용한 컴포넌트 소개  (0) 2019.10.12
캐패시터로 네이티브 앱 만들기  (0) 2019.09.25
아이오닉 튜토리얼  (0) 2018.06.03
반응형

간단하게 ngIf를 이용하여 alert를 이용할 수 있습니다.

 

하지만 3nd-party 라이브러리를 만드는 경우, 그리고 in-code라이브러리를 사용하는 경우에 필요한 기법입니다.

순수하게 프로그래밍으로만 컴포넌트를 만드는 것이죠.

 

방법은 다음과 같습니다.

1. 생성할 Component의 Factory만들기.

2. view container 레퍼런스 (placeholder Directive를 사용하는 거죠.)

3. Angular의 도움을 받아 생성한 Component를 랜더링 합니다.

4. app.module.ts에 entryComponents를 추가합니다.

 

1. Factory생성 및 unsubscribe();

// auth.component.ts
private showErrorAlert(message: string) {
    // const alertCmp = new AlertComponent();
    const alertCmpFactory = this.componentFactoryResolver.resolveComponentFactory(
      AlertComponent
    );
    const hostViewContainerRef = this.alertHost.viewContainerRef;
    hostViewContainerRef.clear();

    const componentRef = hostViewContainerRef.createComponent(alertCmpFactory);

    componentRef.instance.message = message; // alert.component.ts의 @Input() message: string;
    this.closeSub = componentRef.instance.close.subscribe(() => {
      this.closeSub.unsubscribe();
      hostViewContainerRef.clear();
    });
  }

 

2. view container 사용법 <ng-template>를 이용합니다.

<!-- auth.component.html -->
<ng-template appPlaceholder></ng-template>
<div class="row">
  <div class="col-xs-12 col-md-6 col-md-offset-3">
    <!-- <div class="alert alert-danger" *ngIf="error">
      <p>{{ error }}</p>
    </div> -->
    <!-- <app-alert
      [message]="error"
      *ngIf="error"
      (close)="onHandleError()"
    ></app-alert> -->
    <div *ngIf="isLoading" style="text-align: center;">
      <app-loading-spinner></app-loading-spinner>
    </div>
// placeholder.directive.ts
import { Directive, ViewContainerRef } from '@angular/core';

@Directive({
  selector: '[appPlaceholder]'
})
export class PlaceholderDirective {
  constructor(public viewContainerRef: ViewContainerRef) {}
}

3. 랜더링할 컴포넌트 입니다.

// alert.component.ts

import { Component, Input, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'app-alert',
  template: `
  <div class="backdrop" (click)="onClose()"></div>
  <div class="alert-box">
    <p>{{ message }}</p>
    <div class="alert-box-actions">
      <button class="btn btn-primary" (click)="onClose()">Close</button>
    </div>
  </div>`,
  styles: [`
  .backdrop {position: fixed;top: 0;left: 0;width: 100vw;height: 100vh;background: rgba(0, 0, 0, 0.75);z-index: 50;}
  .alert-box {position: fixed;top: 30vh;left: 20vw;width: 60vw;padding: 16px;z-index: 100;background: white;box-shadow: 0 2px 8px rbga(0, 0, 0, 0.26);}
  .alert-box-actions {text-align: right;}
  `]
})
export class AlertComponent {
  @Input() message: string;
  @Output() close = new EventEmitter<void>();

  onClose() {
    this.close.emit();
  }
}

4. entryComponents를 선언합니다.

//app.module.ts
...
bootstrap: [AppComponent],
  entryComponents: [
    AlertComponent
  ]
})
export class AppModule {}

 

*ngIf를 이용하는것이 쉬운 방법이며, Angular의 강력한 도구이기도 합니다.

ngIf가 false인 경우, DOM을 랜더링하지 않습니다.

필요한 경우에만 다이나믹 컴포넌트를 사용하는것이 좋겠죠?

반응형

+ Recent posts