sencha class system, jacky nguyen

46
Wednesday, November 2, 11

Upload: sencha

Post on 15-Jan-2015

5.186 views

Category:

Technology


1 download

DESCRIPTION

Ext JS 4.x and Sencha Touch 2.0 went through a huge refactoring from the ground up with the new class system. It combines the familiar class-based programming style with the dynamic nature of JavaScript into a robust architecture which stands behind every single class written in the frameworks. This session will give you a complete picture of everything our new foundation has to offer as well as their benefits and best practices.Jacky Nguyen is one of the core engineers behind Sencha frameworks. With his well-rounded knowledge and experiences on both server-side and client-side development as well as industry best practices, he is responsible for designing and improving Sencha frameworks’ overall architectures. He was the author of MooTouch, which has become a part of Sencha Labs. Jacky is passionate about bringing innovation to software development and developers.

TRANSCRIPT

Page 1: Sencha Class System, Jacky Nguyen

Wednesday, November 2, 11

Page 2: Sencha Class System, Jacky Nguyen

Jacky Nguyen, SenchaThe Sencha Class [email protected] @nktpro

Wednesday, November 2, 11

Page 3: Sencha Class System, Jacky Nguyen

Best User Experience

Wednesday, November 2, 11

Page 4: Sencha Class System, Jacky Nguyen

BetterDeveloper Experience

Wednesday, November 2, 11

Page 5: Sencha Class System, Jacky Nguyen

Class System

Event System

Data Package

Widgets & Layouts

...

Wednesday, November 2, 11

Page 6: Sencha Class System, Jacky Nguyen

Predictability

Programmer Familiarity

Flexibility

Class-basedPrototype-based

SenchaClass System =

Wednesday, November 2, 11

Page 7: Sencha Class System, Jacky Nguyen

Learn

Develop

Deploy

✓Consistent✓Familiar

✓DRY✓Debuggable✓Testable

✓Automatic dependency resolution

Developer ExperienceBetter Wednesday, November 2, 11

Page 8: Sencha Class System, Jacky Nguyen

Coding Convention

Wednesday, November 2, 11

Page 9: Sencha Class System, Jacky Nguyen

‣ Ext.chart.Label -> Ext/chart/Label.js‣ Ext.data.writer.Xml -> Ext/data/writer/Xml.js‣ MyApp.field.Password -> MyApp/field/Password.js

Namespacing & Code Organization

1. OrganizationName.group[.subgroup].ClassName2. One class per file3. File name matches class name

Wednesday, November 2, 11

Page 10: Sencha Class System, Jacky Nguyen

Class Definition

Wednesday, November 2, 11

Page 11: Sencha Class System, Jacky Nguyen

Ext.ns('My.sample');

My.sample.Person = Ext.extend(Object, { constructor: function(name) { this.name = name; },

walk: function(steps) { alert(this.name + ' is walking ' + steps + ' steps'); }});

The Good Old Ext.extend()

Wednesday, November 2, 11

Page 12: Sencha Class System, Jacky Nguyen

Ext.define('My.sample.Person', { constructor: function(name) { this.name = name; },

walk: function(steps) { alert(this.name + ' is walking ' + steps + ' steps'); }});

var tommy = new My.sample.Developer('Tommy');tommy.walk(5); // alerts 'Tommy is walking 5 steps'

Introducing Ext.define()

Wednesday, November 2, 11

Page 13: Sencha Class System, Jacky Nguyen

‣Class definition is more than just inheritance‣Automatic namespace allocation‣Classes are now aware of their own names‣Asynchronous vs. synchronous

Ext.define() vs Ext.extend()Ext.define('My.sample.Person', { constructor: function(name) { this.name = name; },

walk: function(steps) { alert(this.name + ' is walking ' + steps + ' steps'); }});

Wednesday, November 2, 11

Page 14: Sencha Class System, Jacky Nguyen

Inheritance

Wednesday, November 2, 11

Page 15: Sencha Class System, Jacky Nguyen

Ext.define('My.sample.Person', { constructor: function(name) { this.name = name; }, walk: function(steps) { alert(this.name + ' is walking ' + steps + ' steps'); }});

Ext.define('My.sample.Developer', { extend: 'My.sample.Person', code: function(language) { alert(this.name + ' is coding in ' + language); }});

var tommy = new My.sample.Developer('Tommy');tommy.walk(5); // 'Tommy is walking 5 stepstommy.code('JavaScript'); // 'Tommy is coding in JavaScript'

Inheritance

Wednesday, November 2, 11

Page 16: Sencha Class System, Jacky Nguyen

Ext.define('My.sample.Developer', { extend: 'My.sample.Person', code: function(language) { /* ... */ }, walk: function(steps) { if (steps > 100) { alert('Are you serious? That's too far! I'm lazy...'); } else { } }});

var tommy = new My.sample.Developer('Tommy');tommy.walk(50); // alerts "Tommy is walking 50 steps"tommy.walk(101); // alerts "Are you serious? That's too far! I'm lazy..."

My.sample.Developer.superclass.walk.apply(this, arguments);this.callParent(arguments);

Inheritance

Wednesday, November 2, 11

Page 17: Sencha Class System, Jacky Nguyen

Mixins

Wednesday, November 2, 11

Page 18: Sencha Class System, Jacky Nguyen

Compose Songs

Play Instruments

Sing

Singer-songwriter

Composer

Performer

Mixins

Wednesday, November 2, 11

Page 19: Sencha Class System, Jacky Nguyen

Ext.define('My.ability.Sing', { sing: function(songName) { alert("I'm singing " + songName); }});

Mixins

Ext.define('My.ability.PlayInstruments', { play: function(instrument) { alert("I'm playing " + instrument); }});

Ext.define('My.ability.ComposeSongs', { compose: function(songName) { alert("I'm composing " + songName); }});

Wednesday, November 2, 11

Page 20: Sencha Class System, Jacky Nguyen

Ext.define('My.sample.Performer', { extend: 'My.sample.Person', mixins: { canSing: 'My.ability.Sing', canPlay: 'My.ability.PlayInstruments' }});

Mixins

Ext.define('My.sample.Composer', { extend: 'My.sample.Person', mixins: { canPlay : 'My.ability.PlayInstruments', canCompose: 'My.ability.ComposeSongs' }});

Ext.define('My.sample.SingerSongwriter', { extend: 'My.sample.Person', mixins: { canSing : 'My.ability.Sing', canPlay : 'My.ability.PlayInstruments', canCompose: 'My.ability.ComposeSongs' }});

Wednesday, November 2, 11

Page 21: Sencha Class System, Jacky Nguyen

Ext.define('My.sample.Performer', { extend: 'My.sample.Person', mixins: { canSing: 'My.ability.Sing', canPlay: 'My.ability.PlayInstruments' },

sing: function() { alert("Here we go!");

this.mixins.canSing.sing.call(this);

alert("I'm done singing!"); }});

var jamie = new My.sample.Performer("Jamie");jamie.sing("November Rain"); // alerts "Here we go!" // alerts "I'm singing November Rain" // alerts "I'm done singing!";

Mixins

prototype of

Wednesday, November 2, 11

Page 22: Sencha Class System, Jacky Nguyen

Dependency Management

Wednesday, November 2, 11

Page 23: Sencha Class System, Jacky Nguyen

<!-- ... --><head> <!-- ... -->

<script>

</script></head><!-- ... -->

<script src="My/sample/Developer.js"></script><script src="My/sample/Location.js"></script><script src="My/sample/Person.js"></script>

var tommy = new My.sample.Developer('Tommy');var jamie = new My.sample.Performer('Jamie');

<script src="My/ability/Sing.js"></script><script src="My/ability/PlayInstruments.js"></script>

<script src="My/sample/Performer.js"></script>

var tommy = Ext.create('My.sample.Developer', 'Tommy');var jamie = Ext.create('My.sample.Performer', 'Jamie');

Dependency Management

<script src="ext-all-debug.js"></script><script src="ext.js"></script>

Wednesday, November 2, 11

Page 24: Sencha Class System, Jacky Nguyen

<!-- ... --><head> <!-- ... --> <script src="ext.js"></script> <script>

</script></head><!-- ... -->

Ext.require([ 'My.sample.Developer', 'My.sample.Performer']);

Ext.onReady(function() { var tommy = new My.sample.Developer('Tommy'); var jamie = new My.sample.Performer('Jamie');});

Dependency Management

Wednesday, November 2, 11

Page 25: Sencha Class System, Jacky Nguyen

Config

Wednesday, November 2, 11

Page 26: Sencha Class System, Jacky Nguyen

Ext.define('My.sample.Person', { name: 'Anonymous', age: 0, gender: 'Male',

constructor: function(config) { config = config || {};

Ext.apply(this, config); }});

var robert = new My.sample.Person({ name: 'Robert', age: 21});

Config

Wednesday, November 2, 11

Page 27: Sencha Class System, Jacky Nguyen

Ext.define('My.sample.Person', { name: 'Anonymous', age: 0, gender: 'Male',

constructor: function(config) { if (Ext.isObject(config)) { if (config.hasOwnProperty('name')) { this.name = config.name; } if (config.hasOwnProperty('age')) { this.age = config.age; } if (config.hasOwnProperty('gender')) { this.gender = config.gender; } } }});

Config

Wednesday, November 2, 11

Page 28: Sencha Class System, Jacky Nguyen

Ext.define('My.sample.Person', { name: 'Anonymous', age: 0, gender: 'Male',

constructor: function(config) { if (Ext.isObject(config)) { if (config.hasOwnProperty('name')) { this.setName(config.name); } if (config.hasOwnProperty('age')) { this.setAge(config.age); } if (config.hasOwnProperty('gender')) { this.setGender(config.gender); } } },});

Config

Wednesday, November 2, 11

Page 29: Sencha Class System, Jacky Nguyen

setName: function(name) { this.name = name; return this; }, getName: function() { return this.name; },

setAge: function(age) { this.age = age; return this; }, getAge: function() { return this.age; },

setGender: function(gender) { this.gender = gender; return this; }, getGender: function() { return this.gender; }

Wednesday, November 2, 11

Page 30: Sencha Class System, Jacky Nguyen

Ext.define('My.sample.Person', { config: { name: 'Anonymous', age: 0, gender: 'Male' },

constructor: function(config) { this.initConfig(config); }});

var robert = new My.sample.Person({ name: 'Robert', age: 21});

robert.setName('Rob');alert(robert.getAge()); // alerts '21'robert.setAge(22);alert(robert.getAge()); // alerts '22'

Config

Wednesday, November 2, 11

Page 31: Sencha Class System, Jacky Nguyen

Ext.define('My.sample.Developer', { extend: My.sample.Person, config: { level: 'Junior', location: { city: 'Unknown', state: 'Unknown', country: 'Unknown' } }});

var edward = new My.sample.Developer({ age: 26, level: 'Senior', location: { city: 'Palo Alto', state: 'CA', country: 'USA' }});

edward.setName('Edward');alert(edward.getLocation().city); // alerts 'Palo Alto'

Config: Deep Merging

Wednesday, November 2, 11

Page 32: Sencha Class System, Jacky Nguyen

Before

Set

After

✓Validation✓Filtering✓Transformation

✓Actual assignment

✓Notification✓Updating dependencies

Config: Setter’s Process

Wednesday, November 2, 11

Page 33: Sencha Class System, Jacky Nguyen

Config: Magic MethodsgetFoo()

setFoo()

processedValue = applyFoo(newValue, oldValue)

updateFoo(processedValue, oldValue)

this.foo = processedValueSet

Before

After

return this.foo

Wednesday, November 2, 11

Page 34: Sencha Class System, Jacky Nguyen

Ext.define('My.sample.Person', { /* ... */ applyAge: function(age) { if (typeof age != 'number' || age < 0) { alert("Invalid age, must be a positive number"); return; } return age; }, updateAge: function(newAge, oldAge) { alert("Age has changed from " + oldAge + " to " + newAge); }});

var aaron = new My.sample.Person({ name: 'Aaron', age: -100}); // alerts "Invalid age, must be a positive number"

alert(aaron.getAge()); // alerts 0alert(aaron.setAge(35)); // alerts "Age has changed from 0 to 35"alert(aaron.getAge()); // alerts 35

Config

Wednesday, November 2, 11

Page 35: Sencha Class System, Jacky Nguyen

Dependency Injection with Ext.factory()

Wednesday, November 2, 11

Page 36: Sencha Class System, Jacky Nguyen

Ext.define('My.sample.Location', { config: { city: 'Unknown', state: 'CA', country: 'USA' }});

var nicolas = new My.sample.Developer({ location: { city: 'Palo Alto' }}); alert(nicolas.getLocation() instanceof My.sample.Location); //alerts truealert(nicolas.getLocation().getCity()); // alerts 'Palo Alto'

var nicolas = new My.sample.Developer({ location: new My.sample.Location({ city: 'Austin', state: 'TX' })});

alert(nicolas.getLocation().getState()); // alerts 'TX'

Dependency Injection

Wednesday, November 2, 11

Page 37: Sencha Class System, Jacky Nguyen

nicolas.setLocation({ city: 'Austin'}); // nicolas.getLocation().setCity('Austin');

nicolas.setLocation(new My.sample.Location({ city: 'Austin', state: 'TX'}));

nicolas.setLocation(new My.sample.DetailedLocation({ longitude: -122.18235, latitude: 37.44923}));

Dependency Injection

Wednesday, November 2, 11

Page 38: Sencha Class System, Jacky Nguyen

Ext.define('My.sample.Developer', { extend: 'My.sample.Person',

config: { level: 'Junior', location: {} },

applyLocation: function(location, currentLocation) { return Ext.factory( location, My.sample.Location, currentLocation ); }}); given value from setLocation()default Class existing instance

Ext.factory()

Wednesday, November 2, 11

Page 39: Sencha Class System, Jacky Nguyen

Debugging

Wednesday, November 2, 11

Page 40: Sencha Class System, Jacky Nguyen

Debugging: Nightmare

Wednesday, November 2, 11

Page 41: Sencha Class System, Jacky Nguyen

Debugging: Dream Comes True

Wednesday, November 2, 11

Page 42: Sencha Class System, Jacky Nguyen

Debugging: Dream Comes True

Wednesday, November 2, 11

Page 43: Sencha Class System, Jacky Nguyen

Deployment

Wednesday, November 2, 11

Page 44: Sencha Class System, Jacky Nguyen

Deployment

Ext.Loader.history === [ 'My.sample.Person', 'My.sample.Location', 'My.sample.Developer', 'My.ability.Sing', 'My.ability.PlayInstruments', 'My.ability.ComposeSongs', 'My.sample.Performer', 'My.sample.Composer', 'My.sample.SingerSongwriter', /* ... */ ];

Concatenate Minify app.js

http://www.sencha.com/products/sdk-tools

Wednesday, November 2, 11

Page 45: Sencha Class System, Jacky Nguyen

Summary

Wednesday, November 2, 11

Page 46: Sencha Class System, Jacky Nguyen

Thank you!

Wednesday, November 2, 11