Ember.js – prosty komponent webowy

Ten krótki wpis jest o tym jak stworzyć prosty, fajnie wyglądający komponent webowy do przełączania stanu true/false.  Efekt końcowy jaki chcemy uzyskać ma wyglądać tak:

 

 

Na początek wygenerujemy komponent za pomocą ember cli:

1
 ember g component switch-toggle

co wygeneruje nam 3 pliki: template, plik js komponentu oraz test.

 

Szablon html będzie składał się z dwóch elementów span, po jednym dla opcji On Off:

1
2
3
4
5
6
<span class="{{blockName}}__button {{unless isEnabled (concat blockName '--selected')}}">
  {{offText}}
</span>
<span class="{{blockName}}__button {{if isEnabled (concat blockName '--selected')}}">
  {{onText}}
</span>

Kilka wyjaśnień do powyższego szablonu:

  • {{blockName}} jest sparametryzowaną ogólną klasą css dla całego komponentu, która zostanie dodana do elementu div okalającego komponent za pomocą classNameBidings, w tym wypadku przypiszemy switch-toggle – dobrą praktyką jest otaczanie komponentu właśnie taką klasą według konwencji nazewnictwa BEM
  • {{unless isEnabled (concat blockName '--selected')}}] – unless to skrót od if not, co spowoduje dodanie klasy css switch-toggle--selected gdy wartość isEnabled będzie false
  • offText oraz onText – parametry tekstów wyświetlanych na przyciskach np. Yes lub No

 

Aby zmieniać stan naszego przełącznika On/Off będzie potrzebna akcja onclick, którą możemy umieścić w pliku js naszego komponentu:

1
2
3
4
5
6
7
8
9
10
11
import BaseComponent from './base-component';

export default BaseComponent.extend({
  blockName: 'switch-toggle',
  offText: 'No',
  onText: 'Yes',
  isEnabled: false,
  click() {
    this.toggleProperty('isEnabled');
  }
});

 

Funkcja click() działa na zasadzie konwencji tzn. Ember wie, że przy wygenerowaniu naszego komponentu funkcja o nazwie click() ma być użyta jako akcja po kliknięciu na komponent. Logika tejże funkcji jest oczywista – zmienna isEnabled przyjmuje odwrotną wartość do aktualnie przypisanej true lub false.

Parametr blockName definiuje wyżej opisaną klasę css dla całego komponentu, isEnabled przechowuje aktualną wartość przełącznika.

Użyty w tym przykładzie base-component definiuje logikę przypisania klasy css do wygenerowanego komponentu:

1
2
3
4
5
6
7
8
import { alias } from '@ember/object/computed';
import Component from '@ember/component';

export default Component.extend({
  classNameBindings: ['blockName'],
  blockName: 'base-component',
  bem: alias('blockName'),
});

classNameBindings definiuje listę parametrów, których wartość będzie dodana do komponentu w formie nazwy klasy css. Na podstawie powyższego kodu komponent szuka pola o nazwie blockName i jego wartość uzna za klasę css komponentu. Domyślnie byłaby to klasa base-component, ale jest ona nadpisywana wartością switch-toggle

 

Aby nadać odpowiedni wygląd przyciskowi należy zdefiniować style css. W celu uzyskania efektu z wideo powyżej można stworzyć następujące style (w tym wypadku format 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
@import "report-page";
$widget-background: #EAEBEE;
$color-dark-navy: #505E75;

.switch-toggle {
  color: #606A79;
  display: flex;
  flex-direction: row;
  background-color: $widget-background;
  border-radius: 4px;

  &amp;__button {
    padding: 8px;
    font-size: 12px;
    cursor: pointer;
    min-width: 25px;
  }

  &amp;--selected {
    background-color: $color-dark-navy;
    border-radius: 4px;
    color: white;
    box-shadow: 0 3px 4px 0 rgba(0,0,0,0.1);
  }
}

Wygenerowany przez Ember.js kod html dla naszego komponentu wygląda tak:

 

 

Uzupełnieniem całości powinien być prosty test, który sprawdzi, że po kliknięciu zmieniają się klasy css, co za tym idzie także wartość komponentu.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
import {find} from "ember-native-dom-helpers";

moduleForComponent('switch-toggle', 'Integration | Component | reports switch toggle', {
  integration: true
});

  test('it renders', function(assert) {
  this.set('off', 'off');
  this.set('on', 'on');
  this.render(hbs`{{reports-switch-toggle offText=off onText=on}}`);

  assert.equal(find(".switch-toggle span:first-child").innerText.trim(), 'off');
  assert.equal(find(".switch-toggle span:first-child").className.trim(), 'switch-toggle__button switch-toggle--selected');
  assert.equal(find(".switch-toggle span:last-child").innerText.trim(), 'on');
  assert.equal(find(".switch-toggle span:last-child").className.trim(), 'switch-toggle__button');
  this.$('.reports-switch-toggle').click();

  assert.equal(find(".switch-toggle span:first-child").className.trim(), 'switch-toggle__button');
  assert.equal(find(".switch-toggle span:last-child").className.trim(), 'switch-toggle__button switch-toggle--selected');
});

Mam nadzieję, że ten prosty przykład przełącznika w formularzu html przybliżył Ci trochę koncepcje komponentów Ember.js. Przykład jest dosyć trywialny, ale porusza kilka ciekawych cech framework’a. W przyszłości na pewno dodam więcej bardziej rozbudowanych zagadnień. Na tę chwilę polecam Ci zadawanie pytań oraz pogłębianie wiedzy z dokumentacji 🙂

Posted on: Marzec 26, 2018

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *