lecture 7 introduction to ionic 2 - jan václavíkjanvaclavik.cz/others/codecamp/7.pdf · 6 /95 /95...

95
INTRODUCTION TO IONIC 2 LECTURE 7 DANIEL RYS JAN VÁCLAVÍK

Upload: dinhhanh

Post on 07-Jun-2018

213 views

Category:

Documents


0 download

TRANSCRIPT

I N T R O D U C T I O N T O I O N I C 2

L E C T U R E 7

D A N I E L R Y S J A N VÁ C L AV Í K

/95

O V E R V I E W

• Create new Ionic2 application

• Why Ionic2

• Project structure

• Features

2

/95

I N S TA L L I O N I C 2 & C R E AT E N E W A P P L I C AT I O N

3

$ npm install -g ionic@beta$ ionic start my-first-ionic2-app [tabs|sidemenu|blank] --v2 [--ts]

$ ionic serve

/954

$ npm install -g ionic@beta$ ionic start my-first-ionic2-app [tabs|sidemenu|blank] --v2 [--ts]

$ ionic serve

I N S TA L L I O N I C 2 & C R E AT E N E W A P P L I C AT I O N

Ionic version 2

/955

$ npm install -g ionic@beta$ ionic start my-first-ionic2-app [tabs|sidemenu|blank] --v2 [--ts]

$ ionic serve

Create TypeScript project

I N S TA L L I O N I C 2 & C R E AT E N E W A P P L I C AT I O N

Ionic version 2

/95

• Component-based model

• Angular2

• ES6 / TypeScript (transpiling)

• Windows 10 support, Android Material Design

• Generator

• Better theming & performance

• More scalable structure

W H Y I O N I C 2

6

/95

/95

I can do all this through him

who gives me strength

Philippians 4:13

/95

E C M A S C R I P T 6 / T Y P E S C R I P T

• Classes (OOP)

• Fat arrow (=>)

• Promises

• Components (modules)

• Block scoping

9

/95

C L A S S E S

10

• Mapping real world object into the abstract

class Shape { constructor (id, x, y) { this.id = id this.move(x, y) } move (x, y) { this.x = x this.y = y } }

/95

C L A S S E S

11

• Mapping real world object into the abstract

Constructor is called when creating instance of class

class Shape { constructor (id, x, y) { this.id = id this.move(x, y) } move (x, y) { this.x = x this.y = y } }

/95

FAT A R R O W F U N C T I O N S

12

someFunction(function(response){ console.log(response); });

/95

FAT A R R O W F U N C T I O N S

13

someFunction(function(response){ console.log(response); });

Has local context

/95

FAT A R R O W F U N C T I O N S

14

someFunction(function(response){ console.log(response); });

someFunction((response) => { console.log(response); });

Has local context

/95

FAT A R R O W F U N C T I O N S

15

someFunction(function(response){ console.log(response); });

someFunction((response) => { console.log(response); });

Has local context

Has parent context

/95

P R O M I S E S

16

doSomething().then((response) => { console.log(response); });

For more details see Lecture 5

/95

I M P O R T & E X P O R T C O M P O N E N T S

17

// lib/math.js export function sum (x, y) {return x + y} export var pi = 3.141593

// someApp.js import * as math from "lib/math" console.log("2PI = " + math.sum(math.pi, math.pi))

// otherApp.js import {sum, pi} from "lib/math" console.log("2PI = " + sum(pi, pi))

/95

I M P O R T & E X P O R T C O M P O N E N T S

18

// lib/math.js export function sum (x, y) {return x + y} export var pi = 3.141593

// someApp.js import * as math from "lib/math" console.log("2PI = " + math.sum(math.pi, math.pi))

// otherApp.js import {sum, pi} from "lib/math" console.log("2PI = " + sum(pi, pi))

Specify visible functions, vars

/95

I M P O R T & E X P O R T C O M P O N E N T S

19

// lib/math.js export function sum (x, y) {return x + y} export var pi = 3.141593

// someApp.js import * as math from "lib/math" console.log("2PI = " + math.sum(math.pi, math.pi))

// otherApp.js import {sum, pi} from "lib/math" console.log("2PI = " + sum(pi, pi))

Can call functions from components

Specify visible functions, vars

/95

I M P O R T & E X P O R T C O M P O N E N T S

20

// lib/math.js export function sum (x, y) {return x + y} export var pi = 3.141593

// someApp.js import * as math from "lib/math" console.log("2PI = " + math.sum(math.pi, math.pi))

// otherApp.js import {sum, pi} from "lib/math" console.log("2PI = " + sum(pi, pi))

Can call functions from components

Specify visible functions, vars

/95

I M P O R T & E X P O R T C O M P O N E N T S I N I O N I C 2

21

import {Page} from 'ionic-angular'; import {MoviesPage} from '../movies/movies';

/95

I M P O R T & E X P O R T C O M P O N E N T S I N I O N I C 2

22

import {Page} from 'ionic-angular'; import {MoviesPage} from '../movies/movies';

Import from Ionic

/95

B L O C K S C O P I N G

23

for (let i = 0; i < movies.length; i++) { let x = movies[i]; } console.log(x);

/95

B L O C K S C O P I N G

24

for (let i = 0; i < movies.length; i++) { let x = movies[i]; } console.log(x); // Undefined

/95

T Y P E S C R I P T E X A M P L E

25

function add(x : number, y : number) : number { return x + y; } add('a', 'b');

/95

T Y P E S C R I P T E X A M P L E

26

function add(x : number, y : number) : number { return x + y; } add('a', 'b'); // Compiler error

/9527

D E P E N D E N C Y I N J E C T I O N

/95

D E P E N D E N C Y I N J E C T I O N

28

import {Page, NavController, Platform} from 'ionic-angular'; @Page({ templateUrl: 'build/pages/movies/movies.html' }) export class MoviesPage { static get parameters() { return [[NavController], [Platform]]; } constructor(nav, platform) { this.nav = nav; this.platform = platform; } }

/95

D E P E N D E N C Y I N J E C T I O N

29

import {Page, NavController, Platform} from 'ionic-angular'; @Page({ templateUrl: 'build/pages/movies/movies.html' }) export class MoviesPage { static get parameters() { return [[NavController], [Platform]]; } constructor(nav, platform) { this.nav = nav; this.platform = platform; } }

Constructor is function called when new instance is created

/95

D E P E N D E N C Y I N J E C T I O N

30

import {Page, NavController, Platform} from 'ionic-angular'; @Page({ templateUrl: 'build/pages/movies/movies.html' }) export class MoviesPage { static get parameters() { return [[NavController], [Platform]]; } constructor(nav, platform) { this.nav = nav; this.platform = platform; } } Inject components

to constructorConstructor is function called when new instance is created

/9531

B I N D I N G

/95

B I N D I N G

<input [value]="name">

32

/95

B I N D I N G

33

<input [value]="name">

One-way data binding []

/95

B I N D I N G

34

<input [value]="name">

<button (click)="someFunction($event)"></button>

One-way data binding []

/95

B I N D I N G

35

<input [value]="name">

<button (click)="someFunction($event)"></button>

One-way data binding []

Call function on event ()

/95

B I N D I N G

36

<input [value]="name">

<button (click)="someFunction($event)"></button>

One-way data binding []

<input [value]="name" (input)="name = $event.target.value">

Call function on event ()

/95

B I N D I N G

37

<input [value]="name">

<button (click)="someFunction($event)"></button>

One-way data binding []

<input [value]="name" (input)="name = $event.target.value"> <!-- or --> <input [(ngModel)]="name">

Call function on event ()

/95

B I N D I N G

38

<input [value]="name">

<button (click)="someFunction($event)"></button>

One-way data binding []

Two-way data binding [()]

<input [value]="name" (input)="name = $event.target.value"> <!-- or --> <input [(ngModel)]="name">

Call function on event ()

/95

R E N D E R I N G

39

<p>Hello my name is {{name}} and I like {{thing}}.</p>

/95

R E N D E R I N G

40

<p>Hello my name is {{name}} and I like {{thing}}.</p>

The same as in Angular1

/95

C R E AT E L O C A L VA R I A B L E

41

<p #myParagraph></p> <button (click)="myParagraph.innerHTML = 'Fill element with something...'">

/95

C R E AT E L O C A L VA R I A B L E

42

<p #myParagraph></p> <button (click)="myParagraph.innerHTML = 'Fill element with something...'">

# means variable

/95

D E C O R AT O R S

• Metadata and info about classes

• Directly above class definition

• Starts with @

43

/95

D E C O R AT O R T Y P E S

• @App – Declare class for root component in Angular2

• @Component – Separately usable element (template, style, logic)

• @Page – Ionic-specific component

• @Directive – Modify behavior of existing component

• @Injectable – Inject to constructor, for creating services

• @Pipe – similar with filter in Angular1

• …

44

/95

D E C O R AT O R E X A M P L E

45

import {Page, NavController, Platform} from ‘ionic-angular';

@Page({ templateUrl: 'build/pages/movies/movies.html' }) export class MoviesPage { ... }

/95

D E C O R AT O R E X A M P L E

46

import {Page, NavController, Platform} from ‘ionic-angular';

@Page({ templateUrl: 'build/pages/movies/movies.html' }) export class MoviesPage { ... }

Decorator for Ionic2 page

/95

D E C O R AT O R E X A M P L E

47

import {Page, NavController, Platform} from ‘ionic-angular';

@Page({ templateUrl: 'build/pages/movies/movies.html' }) export class MoviesPage { ... }

Decorator for Ionic2 page

Object with metadata, contains template URL for specific page

/95

D I R E C T I V E S

48

<section *ngIf="showSection"></section> <li *ngFor="#item of items"></li>

Modify behavior of existing component

/95

D I R E C T I V E S

49

<section *ngIf="showSection"></section> <li *ngFor="#item of items"></li>

Array/Object iterator, the same as ng-repeat from Angular1

Modify behavior of existing component

/95

D I R E C T I V E S

50

<section *ngIf="showSection"></section> <li *ngFor="#item of items"></li>

Array/Object iterator, the same as ng-repeat from Angular1

Remember #?

Modify behavior of existing component

/95

D I R E C T I V E S

51

<section *ngIf="showSection"></section> <li *ngFor="#item of items"></li>

Array/Object iterator, the same as ng-repeat from Angular1

Remember #?

Modify behavior of existing component

* Syntactic sugar for <template>

/95

T E M P L AT E E L E M E N T, *

• <template> rendered when script is running

• * is embedded template

• You can work with HTML elements like with <template>

52

/95

L O O P I N G

53

<ion-list> <ion-item *ngFor="#movie of movies" (click)="viewMovie(movie)"> <h2>{{movie.title}}</h2> <p>{{movie.rating}} / 10</p> </ion-item> </ion-list>

/95

I O N I C 2 P R O J E C T S T R U C T U R E

54

!"" app#   !"" app.js#   !"" pages#  #   !"" page1#  #   # !"" page1.html#  #   # !"" page1.js#  #   # $"" page1.scss#   # !"" page2#   # !"" page3#   # $"" tabs#   $"" theme# !"" app.core.scss# !"" app.ios.scss# !"" app.md.scss# !"" app.variables.scss# $"" app.wp.scss!"" config.xml!"" gulpfile.js!"" hooks!"" ionic.config.js!"" ionic.config.json!"" node_modules!"" package.json!"" platforms!"" plugins!"" resources$"" www $"" index.html

/95

I O N I C 2 P R O J E C T S T R U C T U R E

• Do not edit code in WWW directory except index.html!

• Except resources and index.html, everything in www directory is generated automatically from app directory!

55

/9556

I O N I C 2 G E N E R AT O R

/95

I O N I C 2 G E N E R AT O R

• We don’t need to create and include files manually!

• Use Ionic Generator, you will love it

57

$ ionic g [page|component|directive|pipe|provider|tabs] some-name

/95

C R E AT E C O M P O N E N T

58

import {Component} from 'angular2/core'; import {IONIC_DIRECTIVES} from 'ionic-angular'; @Component({ selector: 'my-component', templateUrl: 'build/components/my-component/my-component.html', directives: [IONIC_DIRECTIVES] }) export class MyComponent { constructor() { this.text = 'Hello World'; } }

$ ionic g component my-component

app/components/my-component/my-component.js

/95

C R E AT E C O M P O N E N T

59

import {Component} from 'angular2/core'; import {IONIC_DIRECTIVES} from 'ionic-angular'; @Component({ selector: 'my-component', templateUrl: 'build/components/my-component/my-component.html', directives: [IONIC_DIRECTIVES] }) export class MyComponent { constructor() { this.text = 'Hello World'; } }

Decorator for component

$ ionic g component my-component

app/components/my-component/my-component.js

/95

C R E AT E PA G E

60

$ ionic g page my-page

app/pages/my-page/my-page.js

import {Page, NavController} from 'ionic-angular'; @Page({ templateUrl: 'build/pages/my-page/my-page.html', }) export class MyPagePage { static get parameters() { return [[NavController]]; } constructor(nav) { this.nav = nav; } }

/95

C R E AT E PA G E

61

$ ionic g page my-page

app/pages/my-page/my-page.js

import {Page, NavController} from 'ionic-angular'; @Page({ templateUrl: 'build/pages/my-page/my-page.html', }) export class MyPagePage { static get parameters() { return [[NavController]]; } constructor(nav) { this.nav = nav; } }

Create bundle with JS + HTML + SASS

/95

C R E AT E D I R E C T I V E

62

$ ionic g directive my-super-directive

import {Directive} from 'angular2/core'; @Directive({ selector: '[my-super-directive]' // Attribute selector }) export class MySuperDirective { constructor() { console.log('Hello World'); } }

app/components/my-super-directive/my-super-directive.js

/95

C R E AT E P I P E

63

$ ionic g pipe my-old-pipes

app/pipes/my-old-pipes.js

import {Injectable, Pipe} from 'angular2/core'; @Pipe({ name: 'my-old-pipes' }) @Injectable() export class MyOldPipes { transform(value, args) { value = value + ''; // make sure it's a string return value.toLowerCase(); } }

/95

C R E AT E P R O V I D E R

64

$ ionic g provider my-provider

app/providers/my-provider/my-provider.js

import {Injectable} from 'angular2/core'; import {Http} from 'angular2/http'; import 'rxjs/add/operator/map'; @Injectable() export class MyProvider { static get parameters(){ return [[Http]] } constructor(http) { this.http = http; this.data = null; } load() { if (this.data) return Promise.resolve(this.data); return new Promise(resolve => { this.http.get('path/to/data.json') .map(res => res.json()).subscribe(data => { this.data = data; resolve(this.data); }); }); } }

/95

C O N D I T I O N A L S

65

/95

C O N D I T I O N A L S

66

<div *ngIf="someBoolean">Hello 1</div>

/95

C O N D I T I O N A L S

67

<div *ngIf="someBoolean">Hello 1</div>

<div [ngSwitch]="someValues"> <p *ngSwitchWhen="1">Paragraph 1</p> <p *ngSwitchWhen="2">Paragraph 2</p> <p *ngSwitchWhen="3">Paragraph 3</p> <p *ngSwitchDefault>Paragraph</p> </div>

/95

C O N D I T I O N A L S

68

<div *ngIf="someBoolean">Hello 1</div>

<div [ngSwitch]="someValues"> <p *ngSwitchWhen="1">Paragraph 1</p> <p *ngSwitchWhen="2">Paragraph 2</p> <p *ngSwitchWhen="3">Paragraph 3</p> <p *ngSwitchDefault>Paragraph</p> </div>

<div [hidden]="someBoolean">Hello 2</div>

/95

C O N D I T I O N A L S

69

<div *ngIf="someBoolean">Hello 1</div>

<div [ngSwitch]="someValues"> <p *ngSwitchWhen="1">Paragraph 1</p> <p *ngSwitchWhen="2">Paragraph 2</p> <p *ngSwitchWhen="3">Paragraph 3</p> <p *ngSwitchDefault>Paragraph</p> </div>

<div [hidden]="someBoolean">Hello 2</div>

<div [class.my-custom-class]="someBoolean">Hello 3</div>

/95

N AV I G AT I O N

70

/95

N AV I G AT I O N

• Pop and push to history stack

• push(SomePage) – add to the top of stack

• pop() – delete last page from the stack

71

/95

N AV I G AT I O N E X A M P L E

72

/95

N AV I G AT I O N E X A M P L E

73

<ion-navbar *navbar> <ion-title>movies</ion-title> </ion-navbar>

<ion-content padding class="movies"> <button class="positive" (click)="showDetail()"> Go to detail </button> </ion-content>

app/pages/movies/movies.html

/95

N AV I G AT I O N E X A M P L E

74

<ion-navbar *navbar> <ion-title>movies</ion-title> </ion-navbar>

<ion-content padding class="movies"> <button class="positive" (click)="showDetail()"> Go to detail </button> </ion-content>

Call method for showing another page

app/pages/movies/movies.html

/95

N AV I G AT I O N E X A M P L E

75

<ion-navbar *navbar> <ion-title>movie-detail</ion-title> </ion-navbar>

<ion-content padding class="movie-detail"> <button class="positive" (click)="goBack()"> Go back </button> </ion-content>

app/pages/movie-detail/movie-detail.html

/95

N AV I G AT I O N E X A M P L E

76

<ion-navbar *navbar> <ion-title>movie-detail</ion-title> </ion-navbar>

<ion-content padding class="movie-detail"> <button class="positive" (click)="goBack()"> Go back </button> </ion-content>

Call method for going back

app/pages/movie-detail/movie-detail.html

/95

N AV I G AT I O N – G O T O PA G E

77

import {Page, NavController} from 'ionic-angular'; import {MovieDetailPage} from '../movie-detail/movie-detail'

@Page({ templateUrl: 'build/pages/movies/movies.html', }) export class MoviesPage { static get parameters() { return [[NavController]]; }

constructor(nav) { this.nav = nav; } showDetail() { this.nav.push(MovieDetailPage) } }

app/pages/movies/movies.js

/95

N AV I G AT I O N – G O T O PA G E

78

import {Page, NavController} from 'ionic-angular'; import {MovieDetailPage} from '../movie-detail/movie-detail'

@Page({ templateUrl: 'build/pages/movies/movies.html', }) export class MoviesPage { static get parameters() { return [[NavController]]; }

constructor(nav) { this.nav = nav; } showDetail() { this.nav.push(MovieDetailPage) } }

app/pages/movies/movies.js Import

/95

N AV I G AT I O N – G O T O PA G E

79

import {Page, NavController} from 'ionic-angular'; import {MovieDetailPage} from '../movie-detail/movie-detail'

@Page({ templateUrl: 'build/pages/movies/movies.html', }) export class MoviesPage { static get parameters() { return [[NavController]]; }

constructor(nav) { this.nav = nav; } showDetail() { this.nav.push(MovieDetailPage) } }

app/pages/movies/movies.js Import

Dependency injection

/95

N AV I G AT I O N – G O T O PA G E

80

import {Page, NavController} from 'ionic-angular'; import {MovieDetailPage} from '../movie-detail/movie-detail'

@Page({ templateUrl: 'build/pages/movies/movies.html', }) export class MoviesPage { static get parameters() { return [[NavController]]; }

constructor(nav) { this.nav = nav; } showDetail() { this.nav.push(MovieDetailPage) } }

app/pages/movies/movies.js Import

Dependency injection

Save as class variable

/95

N AV I G AT I O N – G O T O PA G E

81

import {Page, NavController} from 'ionic-angular'; import {MovieDetailPage} from '../movie-detail/movie-detail'

@Page({ templateUrl: 'build/pages/movies/movies.html', }) export class MoviesPage { static get parameters() { return [[NavController]]; }

constructor(nav) { this.nav = nav; } showDetail() { this.nav.push(MovieDetailPage) } }

app/pages/movies/movies.js Import

Dependency injection

Save as class variable

Push MovieDetailPage to the stack

/95

N AV I G AT I O N – G O T O PA G E

82

import {Page, NavController} from 'ionic-angular'; import {MovieDetailPage} from '../movie-detail/movie-detail'

@Page({ templateUrl: 'build/pages/movies/movies.html', }) export class MoviesPage { static get parameters() { return [[NavController]]; }

constructor(nav) { this.nav = nav; } showDetail() { this.nav.push(MovieDetailPage) } }

app/pages/movies/movies.js Import

Dependency injection

Save as class variable

Push MovieDetailPage to the stack

/95

N AV I G AT I O N – G O B A C K

83

import {Page, NavController} from 'ionic-angular';

@Page({ templateUrl: 'build/pages/movie-detail/movie-detail.html', }) export class MovieDetailPage { static get parameters() { return [[NavController]]; }

constructor(nav) { this.nav = nav; }

goBack() { this.nav.pop() } }

app/pages/movie-detail/movie-detail.js

/95

N AV I G AT I O N – G O B A C K

84

import {Page, NavController} from 'ionic-angular';

@Page({ templateUrl: 'build/pages/movie-detail/movie-detail.html', }) export class MovieDetailPage { static get parameters() { return [[NavController]]; }

constructor(nav) { this.nav = nav; }

goBack() { this.nav.pop() } }

app/pages/movie-detail/movie-detail.js

Pop last page from the stack

/95

N AV I G AT I O N – G O T O PA G E W I T H PA S S I N G PA R A M S

85

import {Page, NavController} from 'ionic-angular'; import {MovieDetailPage} from '../movie-detail/movie-detail'

@Page({ templateUrl: 'build/pages/movies/movies.html', }) export class MoviesPage { static get parameters() { return [[NavController]]; }

constructor(nav) { this.nav = nav; }

showDetail() { this.nav.push(MovieDetailPage, { id: 4 }) } }

/95

N AV I G AT I O N – G O T O PA G E W I T H PA S S I N G PA R A M S

86

import {Page, NavController} from 'ionic-angular'; import {MovieDetailPage} from '../movie-detail/movie-detail'

@Page({ templateUrl: 'build/pages/movies/movies.html', }) export class MoviesPage { static get parameters() { return [[NavController]]; }

constructor(nav) { this.nav = nav; }

showDetail() { this.nav.push(MovieDetailPage, { id: 4 }) } }

Second parameter is an object with params

/95

N AV I G AT I O N – G E T PA R A M S

87

import {Page, NavController, NavParams} from 'ionic-angular';

@Page({ templateUrl: 'build/pages/movie-detail/movie-detail.html', }) export class MovieDetailPage { static get parameters() { return [[NavController], [NavParams]]; }

constructor(nav, params) { this.nav = nav; this.params = params; console.log("ID: " + this.params.get("id")); }

goBack() { this.nav.pop(); } }

/95

N AV I G AT I O N – G E T PA R A M S

88

import {Page, NavController, NavParams} from 'ionic-angular';

@Page({ templateUrl: 'build/pages/movie-detail/movie-detail.html', }) export class MovieDetailPage { static get parameters() { return [[NavController], [NavParams]]; }

constructor(nav, params) { this.nav = nav; this.params = params; console.log("ID: " + this.params.get("id")); }

goBack() { this.nav.pop(); } }

Import

/95

N AV I G AT I O N – G E T PA R A M S

89

import {Page, NavController, NavParams} from 'ionic-angular';

@Page({ templateUrl: 'build/pages/movie-detail/movie-detail.html', }) export class MovieDetailPage { static get parameters() { return [[NavController], [NavParams]]; }

constructor(nav, params) { this.nav = nav; this.params = params; console.log("ID: " + this.params.get("id")); }

goBack() { this.nav.pop(); } }

Import

Dependency injection

/95

N AV I G AT I O N – G E T PA R A M S

90

import {Page, NavController, NavParams} from 'ionic-angular';

@Page({ templateUrl: 'build/pages/movie-detail/movie-detail.html', }) export class MovieDetailPage { static get parameters() { return [[NavController], [NavParams]]; }

constructor(nav, params) { this.nav = nav; this.params = params; console.log("ID: " + this.params.get("id")); }

goBack() { this.nav.pop(); } }

Import

Dependency injection

Save as class variable

/95

N AV I G AT I O N – G E T PA R A M S

91

import {Page, NavController, NavParams} from 'ionic-angular';

@Page({ templateUrl: 'build/pages/movie-detail/movie-detail.html', }) export class MovieDetailPage { static get parameters() { return [[NavController], [NavParams]]; }

constructor(nav, params) { this.nav = nav; this.params = params; console.log("ID: " + this.params.get("id")); }

goBack() { this.nav.pop(); } }

Import

Dependency injection

Save as class variable

Get ID from params

/9592

/9593

WORK ON PROJECTS!

/95

Q U E S T I O N S ?

94

/95

@janvaclavik

J A N VÁ C L AV Í K

@danielrys

D A N I E L R Y S

W W W. U S E R T E C H N O L O G I E S . C O M95