2. Rich Mobile Apps with Sencha Touch
Part II – Class System
ExtJs And Sencha - 2 products that form the
Sencha SDK. They are considered the best UI
frameworks ever made for web applications.
As we saw in the previous presentation they
work cross platforms, cross browser but most
importantly they deliver high quality and user
experience that used to exist only in native
applications.
Best User Experience
3. Rich Mobile Apps with Sencha Touch
Part II – Class System
Better
Developer Experience
4. Rich Mobile Apps with Sencha Touch
Part II – Class System
The Sencha Class System was first introduced in Ext JS 4.0 and
was a major step forward in making it easy to build object oriented
JavaScript code. As a core part of the Sencha JavaScript platform, it’s
now a shared component between Ext JS and Sencha Touch 2.
Ext JS and Sencha Touch 2 use the class system internally to
manage dependencies, make code more reusable as well as provide a
rich set of features that are commonly found in other class-based
programming languages.
5. Rich Mobile Apps with Sencha Touch
Part II – Class System
Class
System
Event System
Data Package
Widgets & Layouts
…
6. Rich Mobile Apps with Sencha Touch
Part II – Class System
Why do we call it a class system?
Prototype-based
Class-based
7. Rich Mobile Apps with Sencha Touch
Part II – Class System
Flexibility
Sencha
Class
System
=
Programmer
Familiarity
Predictability
8. Rich Mobile Apps with Sencha Touch
Part II – Class System
Key Benefits
Learn
Develop
• Consistent
• Familiar
• DRY
• Debuggable
• Testable
• Automatic dependency resolution
Deploy
9. Rich Mobile Apps with Sencha Touch
Part II – Class System
Namespacing & Code Organization
1. OrganizationName.group[.subgroup].ClassName
2. One class per file
3. File name matches class name
• Ext.chart.Label
• Ext.data.writer.Xml
• MyApp.field.Password
Ext/Chart/Label.js
Ext/data/writer/Xml.js
MyApp/field/Password.js
10. Rich Mobile Apps with Sencha Touch
Part II – Class System
Class Definition
Ext.define('My.sample.Person', {
constructor: function(name) {
this.name = name;
},
walk: function(steps) {
alert(this.name + ' is walking ' + steps + ' steps');
}
});
Class definition is more than just inheritance
var tommy = new My.sample.Person('Tommy');
Automatic namespace allocation
tommy.walk(5); // alerts 'Tommy is walking 5 steps'
Classes are aware of their own names
Asynchronous vs. synchronous
11. Rich Mobile Apps with Sencha Touch
Part II – Class System
Inheritance
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 steps'
tommy.code('JavaScript');
// 'Tommy is coding in JavaScript'
12. Rich Mobile Apps with Sencha Touch
Part II – Class System
Inheritance
Ext.define('My.sample.Developer', {
extend: 'My.sample.Person',
code: function(language) {
alert(this.name + ' is coding in ' + language);
},
walk: function(steps) {
if (steps > 100) {
alert('Are you serious? That`s too far! I`m lazy');
} else {
return this.callParent(arguments);
}
}
});
var tommy = new My.sample.Developer('Tommy');
tommy.walk(50); // "Tommy is walking 50 steps"
tommy.walk(101);// "Are you serious? That's too far! I'm lazy"
13. Rich Mobile Apps with Sencha Touch
Part II – Class System
MIXINS
Sing
Performer
Play Instruments
Composer
Compose Songs
Singer-songwriter
14. Rich Mobile Apps with Sencha Touch
Part II – Class System
MIXINS
Ext.define('My.ability.Sing', {
sing: function(songName) {
alert('I`m singing ' + songName);
}
});
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);
}
});
15. Rich Mobile Apps with Sencha Touch
Part II – Class System
MIXINS
Ext.define('My.sample.Performer', {
extend: 'My.sample.Person',
mixins: {
canSing: 'My.ability.Sing',
canPlay: 'My.ability.PlayInstruments'
}
});
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'
}
});
16. Rich Mobile Apps with Sencha Touch
Part II – Class System
MIXINS
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('Wind of Change'); // "Here we go!"
// "I`m singing Wind of Change"
// "I`m done singing!"
17. Rich Mobile Apps with Sencha Touch
Part II – Class System
Dependency Management
• Automatic Dependency Injection
<!-- ... -->
<head>
<!-- ... -->
<script src="ext.js"></script>
<script>
var tommy = Ext.create('My.sample.Developer','Tommy');
var jamie = Ext.create('My.sample.Performer','Jamie');
</script>
</head>
18. Rich Mobile Apps with Sencha Touch
Part II – Class System
Dependency Management
• Alternative
<!-- ... -->
<head>
<!-- ... -->
<script src="ext.js"></script>
<script>
Ext.require([
'My.sample.Developer',
'My.sample.Performer'
]);
Ext.onReady(function() {
var tommy = new My.sample.Developer('Tommy');
var jamie = new My.sample.Developer('Jamie');
});
</script>
</head>
<!-- ... -->
19. Rich Mobile Apps with Sencha Touch
Part II – Class System
Config
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);
}
}
}
});
20. Rich Mobile Apps with Sencha Touch
Part II – Class System
Config
/* ... */
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;
},
/* ... */
21. Rich Mobile Apps with Sencha Touch
Part II – Class System
Config
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()); //
robert.setAge(22); alert(robert.getAge());
//
"21"
"22"
22. Rich Mobile Apps with Sencha Touch
Part II – Class System
Config: Setter’s Process
Before
Set
After
• Validation
• Filtering
• Transformation
• Actual assignment
• Notification
• Updating dependencies
23. Rich Mobile Apps with Sencha Touch
Part II – Class System
Config: Magic Methods
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
}); // "Invalid age, must be a positive number"
alert(aaron.getAge());
alert(aaron.setAge(35));
alert(aaron.getAge());
// "0"
// "Age has changed from 0 to 35"
// "35"