Alkalmazások fejlesztése

10. előadás

Horváth Győző
Egyetemi adjunktus
1117 Budapest, Pázmány Péter sétány 1/c., 2.420-as szoba
Tel: (1) 372-2500/1816
horvath.gyozo@inf.elte.hu

Eddig

  • Vastagkliens alkalmazások
  • Ember.js
  • Fejlesztői környezet előállítása
  • (Router, Route, sablonok)
  • (Ember.Object)

Tartalomjegyzék

  • Komponensek
  • Adatok megjelenítése
  • Eseménykezelés, akciók
  • Példaadatok

2. beadandó

Kliensoldali JavaScript

Opcionális

Elvárások

  • progresszív fejlesztés (JavaScript nélkül is működjön)
  • legalább 4 funkció
  • legalább 2 AJAX-os funkció

Dokumentáció

  • Külön fejezetben,
  • Fejezetenként
    • érintett fájlok, kliens és szerver
    • működés leírása
  • legalább 1 szekvenciadiagram a kiszolgálás folyamatáról

Eszközök

Ember Inspector

(Chrome vagy Firefox plugin)

Komponensek

Komponensek

Újrahasznosítható funkcionális egységek

Kinézet + viselkedés

Használat

{{my-comp}}

VAGY

{{#my-comp}}
  Tartalom
{{/my-comp}}

Elnevezés

Kötőjelet tartalmazzon!

A HTML elemekkel való összeütközés elkerülése végett.

Létrehozás, definíció

ember g component my-comp

--> template.hbs
--> component.js

template.hbs

HTML + HBS
{{yield}} {{!--Komponens tartalma--}}

Komponens testreszabása

export default Ember.Component.extend({
  tagName: 'ul',

  classNames: ['primary'],

  classNameBindings: ['isUrgent'],
  isUrgent: true,

  classNameBindings: ['isEnabled:enabled:disabled'],
  isEnabled: false,

  classNameBindings: ['priority'],
  priority: 'highestPriority',

  attributeBindings: ['customHref:href'],
  customHref: 'http://emberjs.com',
});

Feladat

Bontsuk komponensekre az alkalmazást!

  • új hiba
  • lista

Fő koncepció

Data Down Actions Up (DDAU)

Data Down:

Router --> Controller --> Component

Actions Up:

Router <-- Controller <-- Component

Adatok

Komponensek és belső adatok

component.js

export default Ember.Component.extend({
    adattag: 5,
    obj: {
        a: 1,
        b: 2,
    },
});

template.hbs

{{adattag}}
{{obj.a}}

Komponens és külső adatok

Használat

{{my-comp param=42}}

template.hbs

{{param}}

Külső adatok forrása

route --> controller --> template
 ^             ^
 |             |
model  sablon szintű adatok

Controller

ember g controller utvonal
  • route-szintű állapot tartalma
  • nincs elmentve a szerverre
  • route és a komponens összekapcsolása

Sablon szintű adatok

controller.js

export default Ember.Controller.extend({
    sablonadat: "sablonadat",
});

template.hbs (route)

{{sablonadat}}

Modell

route.js

export default Ember.Route.extend({
    // model: function() {
    model() {
        return {
            modelladat: 'modelladat',
        }
    },
});

template.hbs

{{model.modelladat}}

Többszintű útvonalak

  • modell öröklődik
  • model() felülírja
  • controller szintű adat nem öröklődik

Modellek

Ember-data

Ember-data

Ember.js ORM rétege

  • store
  • modellek definiálása
  • modellek közötti kapcsolatok
  • perzisztálás adaptereken keresztül
  • sorosítók megadása

Modell létrehozása

ember g modell probamodell

model.js

export default DS.Model.extend({
  field1: DS.attr('string'),
  field2: DS.attr('number'),
  field3: DS.attr('boolean'),
  field4: DS.attr('date'),
});

Előre rögzített adatok

const ProbaModell =  DS.Model.extend({
  field1: DS.attr(),
  field2: DS.attr(),
  field3: DS.attr(),
});

ProbaModell.reopenClass({
    FIXTURES: [
        {
            id: 1,
            field1: 11,
            field2: 12,
            field3: 13,
        },
        {
            id: 2,
            field1: 21,
            field2: 22,
            field3: 23,
        },
        {
            id: 3,
            field1: 31,
            field2: 32,
            field3: 33,
        },
        {
            id: 4,
            field1: 41,
            field2: 42,
            field3: 43,
        },
    ]
});

export default ProbaModell;

FixtureAdapter

(Elavult)

Létrehozás

ember g adapter application

RestAdapter --> FixtureAdapter

export default DS.FixtureAdapter.extend({
});

Modell műveletek

  • findRecord(modell, id) / peekRecord(modell, id)
  • findAll(modell) / peekAll(modell)
  • queryRecord(modell, filter)
  • query(modell, filter)
var post = this.store.findRecord('post', 1); // => GET /posts/1

var posts = this.store.findAll('post'); // => GET /posts

// GET to /persons?filter[name]=Peter
this.store.query('person', { filter: { name: 'Peter' } }).then(function(peters) {
  // `peters`
});

Modell használata

route.js

export default Ember.Route.extend({
    model() {
        return this.store.find('probamodel', 1);
    },
});

Feladat

Jelenítsük meg a listát rögzített adatok segítségével!

Események

Események és akciók

Eseménykezelés

export default Ember.Component.extend({
  click: function() {
    // ...
    return true;
  }
});

Lehetséges események

Akciók és kezelésük

template.hbs

<p {{action "actionName"}}>click</p>

<p {{action "actionName" on="mouseUp"}}>click</p>

<p {{action "actionName" param}}>click</p>

<a href="newPage.htm" {{action "logClick" preventDefault=false}}>Go</a>

component.js vagy controller.js vagy route.js

actions: {
  actionName() {
    // ...
  }
},

1. Actions up: closure actions (új)

Függvény mint paraméter, és annak meghívása

Szülő komponens sablon:

{{child-comp onClick=(action 'logClick') }}

Szülő komponens akciókezelő:

export default Ember.Component.extend({
  actions: {
    logClick(value) {
      console.log(value);
    }
  }
}

1. Actions up: closure actions (új)

Függvény mint paraméter, és annak meghívása

Gyerek komponens akciókezelő:

export default Ember.Component.extend({
  click() {
    this.get('onClick')('érték');
  }
});

2. Actions up: action bubbling (régi)

Szülő komponens sablon:

{{child-comp onClick='logClick' }}

Szülő komponens akciókezelő:

export default Ember.Component.extend({
  actions: {
    logClick(value) {
      console.log(value);
    }
  }
}

2. Actions up: action bubbling (régi)

Gyerek komponens akciókezelő:

export default Ember.Component.extend({
    click() {
        this.sendAction('onClick', 'érték');
    }
});

Feladatok

1. feladat

Készíts a Rólunk (about) oldalon egy GYIK-ot: egy kérdés-felelet listát. Eleinte ne jelenjen meg a válasz. Ha rákattintunk a kérdésre, akkor jelenjen meg a válasz.

2. feladat

A Hibakezelő alkalmazásban oldd meg egy hiba felvételét, majd jelenítsd meg a listában:

  • új űrlap mint komponens
  • ellenőrzés a komponensen belül
  • hiba kiírása
  • jó adatok visszaadása a controllerbe
  • controllerben adatok mentése