ExtJS i razvoj modernih korisničkih interfejsa

U današnje vreme se sve više i više razvijaju aplikacije koje rade na svim platformama (Windows, Linux, Mac OS). Jedan način na koji je to moguće postići je upotreba Web tehnologije za razvoj aplikacija. Koncept korišćenja Web tehnologija za razvoj aplikacija je osmišljen tako da se jednom napiše a koristi svuda. Kada sa napravi aplikacija na ovakav način, postavi se u kontejner (container) kao što je Electron ili možda sam Chromium i na taj način je dovoljno da aplikacija koja radi na Web pretraživačima može da se koristi i kao desktop aplikacija. Jedan od okvira (framework-a) koji se koriste je ExtJS razvijen od strane kompanije Sencha i služi za pravljenje profesionalnih aplikacija.

ExtJS olakšava razvoj aplikacija za rad sa velikim količinama podataka za desktop, tablet i smart uređaje. Razvijen je u programskom jeziku Javascript i sastoji se iz dva dela:

  • Sencha CMD – aplikacija za upravljanje ExtJS projektima kroz komandnu liniju,
  • ExtJS framework – sam framework koji je potreban Sencha CMD aplikaciji da bi operisala projektima.

Sencha CMD

Sencha CMD se bavi upravljanjem životnog ciklusa projekta, minimizacijom kôda, pretvaranjem kôda iz ES6 u ES koji svaki Web pretraživač podržava, dinamičko učitavanje paketa, generisanje build-ova za progresivne Web aplikacije, itd.

Preuzimanje

Sencha CMD se preuzima sa linka: https://www.sencha.com/products/extjs/cmd-download/.

Postoje dve verzije instalacije:

  • Sa JRE-om – izaberite ovu verziju u slucaju da nemate JRE ili JDK
  • Bez JRE-a – izaberite ovu verziju u slucaju da imate JRE ili JDK

Instaliranje

Instalacija je jednostavna i intuitivna, samo je potrebno pratiti uputstva u toku same instalacije i neće biti nikakvih problema.

Osnovne komande

Neke od osnovnih komandi su:

  • Generisanje ExtJS projekta/aplikacije

sencha -sdk generate app

  • Pokretanje razvojne verzije aplikacije (potrebno je biti u direktorijumu aplikacije)

sencha app watch

  • Kreiranje radne verzije aplikacije (potrebno je biti u direktorijumu aplikacije)

sencha app build

ExtJS framework

ExtJS framework sadrži preko 115 integrisanih komponenti, a neke od komponenti su: kalendar, tabele, grafikoni… Tabele i grafikoni mogu da obrade milione podataka sa lakoćom. Framework sadrži i robustan paket za podatke koji može da pribavi podatke sa bilo kog standardnog izvora. Takođe pruža mogućnost vizualizacije i analize podataka korišćenjem Sencha Pivot tabele i D3 adapter-a.

Preuzimanje

Besplatna verzija ExtJS framework-a (GPLv3) se preuzima sa linka: https://www.sencha.com/legal/gpl/

Instaliranje

Instalacija se vrši tako što se putanja ka raspakovanom ExtJS framework-u navede pri generisanju novog projekta/aplikacije

Struktura projekta

.sencha/                        # Sencha-specific files (primarily configuration) app/                        # Application-specific content sencha.cfg              # Application configuration file for Sencha Cmd Boot.js                 # Private, low-level dynamic loader for JS and CSS Microloader.js          # Loads app based on app.json content build-impl.xml          # Standard application build script *-impl.xml              # Implementations of various build phases defaults.properties     # Default values and docs for build properties ext.properties          # Build property values specific to Ext JS *.defaults.properties   # Build properties by environment (e.g. "testing") plugin.xml              # Application-level plugin for Sencha Cmd codegen.json            # Data for merging generated code during upgrade workspace/                  # Workspace-specific content (see below) sencha.cfg              # Workspace configuration file for Sencha Cmd plugin.xml              # Workspace-level plugin for Sencha Cmd` ext/                            # A copy of the Ext JS SDK cmd/                        # Framework-specific content for Sencha Cmd sencha.cfg              # Framework configuration file for Sencha Cmd classic/                    # Packages related to the Classic Toolkit classic/                # Ext JS Classic Toolkit package theme-neptune/          # Classic Toolkit Theme Package for Neptune theme-triton/           # Classic Toolkit Theme Package for Triton ... modern/                     # Packages related to the Modern Toolkit modern/                 # Ext JS Modern Toolkit package theme-neptune/          # Modern Toolkit Theme Package for Neptune theme-triton/           # Modern Toolkit Theme Package for Triton ... packages/                   # Framework supplied packages charts/                 # Charts package ux/                     # Contents of "Ext.ux" namespace ... index.html                      # The entry point to your application app.json                        # Application manifest app.js                          # Launches the Application class app/                            # Your application's source code in MVC structure model/                      # Folder for application model classes store/                      # Folder for application stores view/                       # Folder for application view classes main/                   # Folder for the classes implementing the Main View Main.js             # The Main View MainModel.js        # The `Ext.app.ViewModel` for the Main View MainController.js   # The `Ext.app.ViewController` for the Main View Application.js              # The `Ext.app.Application` class packages/                       # Sencha Cmd packages workspace.json                  # Workspace JSON descriptor build/                          # The folder where build output is placed 

Razvoj aplikacije i razvojni šablon

Sam razvoj je moguć u tri direktorijuma:

  • app/ – razvoj za classic i modern verzije
  • classic/ – razvoj samo za classic verziju
  • modern/ – razvoj samo za modern verziju

Aplikaciju je moguće razvijati koristeći MVC i/ili MVVM razvojni šablon.

Dokumentacija

Dokumentacija se nalazi na linku: https://docs.sencha.com

U okviru dokumentacije su detaljno objašnjeni i Sencha CMD i ExtJS framework. U ExtJS dokumentaciji se takođe nalaze primeri za svaku komponentu.

Primer – Kalkulator

Kao primer korišćenja ovog framework-a ćemo napraviti aplikaciju pod nazivom Kalkulator. U okviru ove aplikacije ćemo iskoristiti Viewport, Window, Button, View, ViewModel, ViewController i Table Layout. Na početku generišemo novu aplikaciju koristeći komandu navedenu u prethodnom poglavlju. Nazvaćemo je Calculator u našem slučaju.

U direktorijumu classic/src/view ćemo napraviti novu klasu Viewport koja proširuje Ext.container.Viewport i u njoj ćemo za početak da imamo samo osnovnu konfiguraciju:

Ext.define('Calculator.view.Viewport', { extend: 'Ext.container.Viewport',` requires: ['Calculator.view.main.Main'], items: [{ xtype: 'main' }] }); 

Items konfiguracija služi da se navedu komponente koje će se nalaziti na ovom Viewport-u, a xtype je naziv komponente, u našem slučaju main. Nakon što smo napravili Viewport klasu, potrebno je izmeniti Main klasu u direktorijumu classic/src/view/main tako da izgleda ovako:

Ext.define('Calculator.view.main.Main', { extend: 'Ext.window.Window', xtype: 'main',` requires: [ 'Calculator.view.main.MainModel' ], autoShow: true, controller: 'main', resizable: false, viewModel: { type: 'main' }, width: 200, height: 200 }); 

Ova klasa nam je Window (proširuje Window klasu od ExtJS framework-a) i veličine je 200×200. Da bi ovo sve do što smo do sada uradili zapravo bilo vidljivo, potrebno je dodati Viewport klasu u app.js koji se nalazi u samom direktorijumu aplikacije. Ovaj fajl bi trebalo da izgleda ovako:

/* * This file is generated and updated by Sencha Cmd. You can edit this file as * needed for your application, but these edits will have to be merged by * Sencha Cmd when upgrading. */ Ext.application({ name: 'Calculator', extend: 'Calculator.Application', requires: [ 'Calculator.view.Viewport' ], // The name of the initial view to create. With the classic toolkit this class // will gain a "viewport" plugin if it does not extend Ext.Viewport. With the // modern toolkit, the main view will be added to the Viewport. // mainView: 'Calculator.view.Viewport' //------------------------------------------------------------------------- // Most customizations should be made to Calculator.Application. If you need to // customize this file, doing so below this section reduces the likelihood // of merge conflicts when upgrading to new versions of Sencha Cmd. //------------------------------------------------------------------------- }); 

Aplikacija trenutno izgleda ovako:

Ovo kaže našoj aplikaciji koji je početni View koji se učitava. Dalje je potrebno da dovršimo izgled Kalkulatora. U našoj Main klasi ćemo dodati komponente koje su nam potrebne (Button-i, Header) i da postavimo odgovarajući Layout (raspored). Pored komponenti, imamo Defaults konfiguraciju, koja označava vrednosti konfiguracija za ostale komponente koje koristimo. U našem slučaju smo rekli da su sve komponente dimenzija 50×50, da imaju CSS klasu btn i da imaju onClickNumber handler (funkcija koja se poziva kada se klikne na Button). konfiguracije koje su postavljene kao default (podrazumevane) mogu da se izmene u okviru same komponente (na primer button-i za operacije imaju drugi handler i drugu CSS klasu). Nakon svih izmena naša klasa bi trebalo da izgleda ovako:

Ext.define('Calculator.view.main.Main', { extend: 'Ext.window.Window', xtype: 'main',` requires: [ 'Calculator.view.main.MainModel' ], autoShow: true, controller: 'main', defaults: { width: 50, height: 50, cls: 'btn', handler: 'onClickNumber' }, defaultType: 'button', header: { items: [{ xtype: 'displayfield', bind: { value: '{display}' }, cls: 'display', colspan: 4, height: 60, padding: 0, width: 200 }] }, layout: { type: 'table', columns: 4 }, resizable: false, viewModel: { type: 'main' }, items: [{ cls: 'btn-green', colspan: 2, handler: 'onClickClear', text: 'C', width: 100 }, { cls: 'btn-green', handler: 'onClickChangeSign', text: '+/-' }, { cls: 'btn-orange', handler: 'onClickOp', text: '÷' }, { text: '7' }, { text: '8' }, { text: '9' }, { cls: 'btn-orange', handler: 'onClickOp', text: '×' }, { text: '4' }, { text: '5' }, { text: '6' }, { cls: 'btn-orange', handler: 'onClickOp', text: '-' }, { text: '1' }, { text: '2' }, { text: '3' }, { cls: 'btn-orange', handler: 'onClickOp', text: '+' }, { colspan: 2, text: '0', width: 100 }, { handler: 'onClickDot', text: '.' }, { cls: 'btn-orange', handler: 'onClickOp', text: '=' }] }); 

Nakon Main View-a, prelazimo na ViewModel koji nam služi za dvosmerno povezivanje podataka koji se prikazuju korisniku sa View-om. ViewModel se nalazi u direktorijumu app/view/main, pod nazivom MainModel. U njemu ćemo da definišemo samo promenljivu za rezultat koja će da se prikaže korisniku. On bi trebalo ovako da izgleda ovako:

Ext.define('Calculator.view.main.MainModel', { extend: 'Ext.app.ViewModel', alias: 'viewmodel.main', data: { display: 0.0 } }); 

Najzad nam je ostao još samo ViewController, odnosno kreiranje svih onih handler funkcija koje smo naveli u Main View-u. ViewController se nalazi u direktorijumu app/view/main pod nazivom MainController. U okviru njega ćemo da definišemo našu konfiguraciju State, koja će pamtiti trenutno stanje (trenutna operacija, trenutni rezultat, operande…) i funkcije. On bi trebao da ovako da izgleda:

Ext.define('Calculator.view.main.MainController', { extend: 'Ext.app.ViewController', alias: 'controller.main', state: { operatorClicked: false, selectedOperator: null, dotClicked: false, op1: 0, numberClicked: false, sign: true, decimal: false }, onClickClear: function(){ var vm = this.getViewModel(); vm.set('display', '0'); this.state.selectedOperator = null; this.state.op1 = 0; this.state.isPositive = true; this.state.decimal = false; this.state.sign = true; }, onClickChangeSign: function(){ var vm = this.getViewModel(); var cur = vm.get('display'); if (cur != '0') { if (this.state.sign === true) { vm.set('display', '-' + cur); } else { vm.set('display', cur.toString().substring(1)); } } this.state.sign = !this.state.sign; }, onClickOp: function(btn){ if (this.state.selectedOperator != null && this.state.numberClicked === true) { var vm = this.getViewModel(); var op2 = parseFloat(vm.get('display')); var op1 = parseFloat(this.state.op1); var result = 0; switch (this.state.selectedOperator) { case '+': result = op1 + op2; break; case '-': result = op1 - op2; break; case '×': result = op1 * op2; break; case '÷': result = op1 / op2; break; } vm.set('display', Math.round(result * 100) / 100); this.state.selectedOperator = null; } if (btn.text != '=') { this.state.operatorClicked = true; } this.state.selectedOperator = btn.text; this.state.numberClicked = false; }, onClickDot: function(btn){ if (this.state.decimal === false) { var vm = this.getViewModel(); vm.set('display', vm.get('display') + '.'); } }, onClickNumber: function(btn){ this.state.numberClicked = true; if (this.state.selectedOperator === '=') { this.onClickClear(); } var vm = this.getViewModel(); if (this.state.operatorClicked === true) { this.state.op1 = vm.get('display'); vm.set('display', btn.text); this.state.operatorClicked = false; } else { var cur = vm.get('display'); if (cur == '0') { cur = ''; } vm.set('display', cur + btn.text); } } }); 

Aplikacija trenutno izgleda ovako:

Nakon svega ovoga smo napravili Kalkulator koji ne izgleda baš najbolje (trenutno je potpuno plav ako ga pokrenete sa Sencha CMD). Da bismo poboljšali izgled, dodaćemo CSS (u slučaju ExtJS framework-a, koristi se SASS). SASS fajl koji nama treba za aplikaciju se nalazi u direktorijumu classic/sass/src/view/main pod nazivom Main. Pošto cilj ovog članka nije CSS/SASS, neće biti dato objašnjenja za ovaj deo. Ovaj fajl bi trebao da izgleda ovako:

.btn:hover { background-color: #C7C7C7 !important; } .btn-orange:hover { background-color: #D07B32 !important; } .btn-green:hover { background-color: #A1C9AC !important; } .btn, .btn.x-btn-focus.x-btn-default-small { background-color: #E0E0E0; } .btn-orange, .btn-orange.x-btn-focus.x-btn-default-small { background-color: #F5923E; } .btn-green, .btn-green.x-btn-focus.x-btn-default-small { background-color: #AFDCBB; } .x-btn-focus.x-btn-default-small, .x-btn-focus.x-btn-over.x-btn-default-small { box-shadow: none; } .btn-orange span, .display div { color: #FFFFFF !important; } .display { background-color: #69787F; padding: 0px !important; } .btn span, .btn-orange span, .btn-green span { font-size: 18px; line-height: 22px; color: #000000; } .btn-orange, .btn, .display, .btn-green { border-radius: 0; border-color: #89898C; border-width: 0.5px; } .display div { font-size: 24px; line-height: 32px; text-align: right; padding-right: 5px; padding-top: 10px; } td div { margin-bottom: 0px !important; } .x-window-header-default-top { padding: 0px !important; top: 0px !important; left: 0px !important; } 

Preuzimanje

Urađenu aplikaciju možete da preuzmete sa linka Calculator.tar.gz