Slide 1

Slide 1 text

Copyright Sencha Inc. 2014 Mats Bryntse, founder of Bryntum Building Ext JS 5 Components @Bryntum

Slide 2

Slide 2 text

Intro | Content Basics Design phase Tips & Tricks • Ext class system • Extending a class • Component model • Choose base class • Architecture • Mixins, plugins • Destructor • Writing testable code • Avoiding private Ext code

Slide 3

Slide 3 text

Intro | Quick poll Hands up: Who’s built an Ext JS component?

Slide 4

Slide 4 text

Basics | Background One of the top strengths of Ext JS: Mature reusable UI components.

Slide 5

Slide 5 text

Basics | Background In 2009, I started Bryntum to build UI components

Slide 6

Slide 6 text

Basics | Background

Slide 7

Slide 7 text

Basics | Background

Slide 8

Slide 8 text

Basics | Background

Slide 9

Slide 9 text

Ext JS Class System Introduction

Slide 10

Slide 10 text

Class system | Ext.define Ext.define("MyApp.FilterField", {
 extend : "Ext.form.TextField", requires : ["Ext.other.Class"],
 width : 150,
 … })

Slide 11

Slide 11 text

Class system | Component life cycle Ext.define("MyApp.FilterField", {
 extend : "Ext.form.TextField",
 
 initComponent : function() { … }, afterRender : function() { … }, onDestroy : function() { … },
 … });

Slide 12

Slide 12 text

Class system | Component model Constructor Initialize Render Destroy Component life cycle

Slide 13

Slide 13 text

Class system | Advanced Ext.define("MyApp.FilterField", {
 extend : “Ext.some.Class”,
 
 onClassExtended : function() { … }, … }, function() { … }) // Class def callback

Slide 14

Slide 14 text

Design Phase Choices…

Slide 15

Slide 15 text

Design phase | Choosing a base class or… UI Class Pure JS class?
foo

Slide 16

Slide 16 text

Design phase | Choosing a base class ? or… Extending built-in cmp Custom UI cmp? ?

Slide 17

Slide 17 text

Design phase | Choosing a base class Non-UI class should extend Ext.Base or Ext.util.Observable Ext.define("MyApp.SomeClass", {
 extend : “Ext.Base” // Or omit this });

Slide 18

Slide 18 text

Design phase | Choosing a base class For custom UI classes, you have more choices: Ext.Component Ext.Panel Ext.Container
Foo

Slide 19

Slide 19 text

Design phase | Abstractions Use the right Ext JS abstraction level Native DOM Ext JS “DOM Core” Ext.Component HtmlElement, doc.getElementById JS API, Ext.Element, Ext.get Sizing, life cycle Ext.Container Layout, contain other components

Slide 20

Slide 20 text

Design phase | Task board Let’s look under the hood of the Task Board component

Slide 21

Slide 21 text

Design phase | Task board

Slide 22

Slide 22 text

Design phase | Task board Ext.Panel[layout=hbox]

Slide 23

Slide 23 text

Design phase | Task board Ext.Panel[layout=hbox] Ext.Panel[layout=fit]

Slide 24

Slide 24 text

Design phase | Task board Ext.Panel[layout=hbox] Ext.Panel[layout=fit] Ext.Container[layout=vbox]

Slide 25

Slide 25 text

Design phase | Task board Ext.Panel[layout=hbox] Ext.Panel[layout=fit] Ext.DataView Ext.Container[layout=vbox]

Slide 26

Slide 26 text

Design phase | Task board Let’s verify using the Siesta component inspector

Slide 27

Slide 27 text

Design phase | Configuration Setting proper default properties

Slide 28

Slide 28 text

Design phase | Configuration •Avoid too many mandatory config settings •Provide reasonable defaults •For reusable components: Avoid using public API configs internally cls, style, listeners

Slide 29

Slide 29 text

Design phase | Configuration

Slide 30

Slide 30 text

Design phase | Configuration

Slide 31

Slide 31 text

Design phase | Configuration {viewPreset}, {startDate}, {endDate}

Slide 32

Slide 32 text

Design phase | Configuration {resourceStore} {viewPreset}, {startDate}, {endDate}

Slide 33

Slide 33 text

Design phase | Configuration {resourceStore} {eventStore} {viewPreset}, {startDate}, {endDate}

Slide 34

Slide 34 text

Design phase | Configuration {resourceStore} {eventStore} {rowHeight} { {viewPreset}, {startDate}, {endDate}

Slide 35

Slide 35 text

Design phase | Configuration Scheduler v1.0 new Sch.panel.SchedulerGrid({
 renderTo : document.body, viewPreset : “dayAndWeek”, startDate : new Date(2014, 11, 1), endDate : new Date(2015, 11, 1), eventStore : new Sch.data.EventStore(), resourceStore : new Sch.data.ResourceStore(), rowHeight : 25, …
 });


Slide 36

Slide 36 text

Design phase | Configuration Scheduler v3.0 Ext.define(“Sch.panel.SchedulerGrid”, {
 viewPreset : “dayAndWeek”, rowHeight : 25, initComponent : function() { Ext.applyIf(this, { startDate : new Date(), eventStore : new Sch.data.EventStore(), resourceStore : new Sch.data.ResourceStore()
 }); });

Slide 37

Slide 37 text

Design phase | Configuration Scheduler v3.0 new Sch.panel.SchedulerGrid({
 renderTo : document.body });


Slide 38

Slide 38 text

Mixins & Plugins Code reusability

Slide 39

Slide 39 text

Mixins & Plugins | Mixins •Mixins are just simple objects •Mixins make code reusable for classes •We use them extensively

Slide 40

Slide 40 text

Mixins & Plugins | Mixins •Very simple to use! Ext.define(“My.Mixin”, {
 foo : “bar” });
 Ext.define(“My.awesome.Class”, {
 mixins : [“My.Mixin”] });


Slide 41

Slide 41 text

Mixins & Plugins | Mixins

Slide 42

Slide 42 text

Mixins & Plugins | Plugins •Works for any Ext.Component •Easy way to enable extra functionality for instances •Avoids class bloat, Ext grid is a great example •Ext JS grid has tons of “optional” features

Slide 43

Slide 43 text

Mixins & Plugins | Plugins Row expander, cell editing, row editing, header drag drop, header resize, row drag drop…

Slide 44

Slide 44 text

Mixins & Plugins | Plugins •By using mixins, the core part of the Grid stays manageable •If you don’t use feature X, Sencha Cmd will not include it

Slide 45

Slide 45 text

Mixins & Plugins | Plugins Ext.define(“My.Plugin”, { extend : “Ext.AbstractPlugin”,
 init : function(component) {…} });
 new My.awesome.Class({
 plugins : [new My.Plugin()] });
 Definition: Usage:

Slide 46

Slide 46 text

Mixins & Plugins | Plugins

Slide 47

Slide 47 text

Tips & Tricks Some useful bits of info

Slide 48

Slide 48 text

Rounding up | Tips & tricks Stay on top of the API as much as possible Upgrade pains to be expected otherwise If you must override a private Ext JS method, document it We detect private overrides through tests

Slide 49

Slide 49 text

Rounding up | Tips & tricks

Slide 50

Slide 50 text

Rounding up | Tips & tricks Overriding Ext JS Ext.define("MyApp.view.UserCombo", {
 extend : “Ext.form.ComboBox",
 // TODO document!
 onExpand : function() {
 
 } });
 Always question these! Other solutions? Use a listener?

Slide 51

Slide 51 text

Rounding up | Tips & tricks Forgetting to remove event listeners. Ext.define("MyApp.view.UserList", {
 extend : "Ext.some.Class",
 
 initComponent : function() {
 this.store.on('load', this.onLoad, this);
 }, onLoad : function() { … }
 });


Slide 52

Slide 52 text

Rounding up | Tips & tricks Use onDestroy hook to remove event listeners. Or cmp.mon Ext.define("MyApp.view.UserList", {
 extend : "Ext.some.Class",
 
 initComponent : function() {
 this.store.on('load', this.onLoad, this);
 }, onDestroy : function() { this.store.un('load', this.onLoad, this);
 } });

Slide 53

Slide 53 text

Rounding up | Testing Writing testable code Models & Stores are pure JS, not tied to DOM Very easy to test. Very fast. Views & controllers are much harder

Slide 54

Slide 54 text

Rounding up | Testing Don’t forget to test Component Maker Test Pack on Github https://github.com/matsbryntse/Component-maker-test-pack Yes, you must test your component in IE too.

Slide 55

Slide 55 text

Rounding up | Links •//bryntum.com/products/ •//bryntum.com/docs/siesta •//github.com/matsbryntse/Component-maker-test-pack •//extjs.eu/ by Saki

Slide 56

Slide 56 text

Rounding up | Questions Questions? Twitter: @Bryntum