app framework — you’ve been wanting this
DESCRIPTION
A discussion about YUI's App Framework and how this suite of components provides the right type of foundation and structure for you to build your web applications with. We'll discuss the components of the App Framework that were released in 3.4.0, plus the new exciting stuff we've been working on for 3.5.0! Photos Near Me ( http://photosnear.me ) is an application that shows off the power of the App Framework and is using the newest components; the source is available on GitHub at: https://github.com/ericf/photosnear.me.TRANSCRIPT
YUI App FrameworkYou’ve Been Wanting This
Eric Ferraiuolo@ericf
MVC
♥ Backbone
Model
Y.Model
• Manages data/state
• Observable attributes
• Coalesced change event
• Contains business logic
• Has data-syncing layer
Y.ModelList
foo
foo
foo
foo
foo
foo
foo
set()
1
2
3
4
5
6
7
Y.ModelList
foo
foo
foo
foo
foo
foo
foo
}foo:changeset()
1
2
3
4
5
6
7
View
Y.View
• Containment
• Render-able (you provide rendering logic)
• BYO-Template
• Declarative event subscriptions
• Lightweight
Router
Y.Controller Y.Router
• Basic navigation management
• Uses HTML5 pushState & popstate
• Degrades to hash-based history
• Bookmark-able URLs
• Browser back/forward buttons work!
• Wire-up application states to routes
Y.Router Examplevar router = new Y.Router();
router.route('/library/:lib/', function (req) { var lib = req.params.lib; if (lib === 'yui') { Y.log('YUI Library is awesome!'); }});
router.save('/library/yui/');// => 'YUI Library is awesome!'
Y.Router Examplevar router = new Y.Router();
router.route('/library/:lib/', function (req) { var lib = req.params.lib; if (lib === 'yui') { Y.log('YUI Library is awesome!'); }});
router.save('/library/yui/');// => 'YUI Library is awesome!'
Y.Router Examplevar router = new Y.Router();
router.route('/library/:lib/', function (req) { var lib = req.params.lib; if (lib === 'yui') { Y.log('YUI Library is awesome!'); }});
router.save('/library/yui/');// => 'YUI Library is awesome!'
Y.Router Examplevar router = new Y.Router();
router.route('/library/:lib/', function (req) { var lib = req.params.lib; if (lib === 'yui') { Y.log('YUI Library is awesome!'); }});
router.save('/library/yui/');// => 'YUI Library is awesome!'
Y.Router Examplevar router = new Y.Router();
router.route('/library/:lib/', function (req) { var lib = req.params.lib; if (lib === 'yui') { Y.log('YUI Library is awesome!'); }});
router.save('/library/yui/');// => 'YUI Library is awesome!'
Y.Router Examplevar router = new Y.Router();
router.route('/library/:lib/', function (req) { var lib = req.params.lib; if (lib === 'yui') { Y.log('YUI Library is awesome!'); }});
router.save('/library/yui/');// => 'YUI Library is awesome!'
Y.Router Mechanics
Y.Router
Y.History
history:change
popstate
hashchange
pushState()
save/replace()
Built on Solid Core
•Y.Base
•Y.Attribute
•Y.EventTarget
•Y.io
•Y.JSON
•Y.Array
•Y.ArrayList
•Y.Node
•Y.History
4.6KB
BIGCommunity Adoption
What’s ComingApp Framework — 3.5.0
Y.App
Foundation and Structure
Sample Users Appvar usersApp = new Y.App({ views: { users: { type : Y.UsersView, preserve: true },
user: { type : Y.UserView, parent: 'users' } }});
Sample Users Appvar usersApp = new Y.App({ views: { users: { type : Y.UsersView, preserve: true },
user: { type : Y.UserView, parent: 'users' } }});
Sample Users Appvar usersApp = new Y.App({ views: { users: { type : Y.UsersView, preserve: true },
user: { type : Y.UserView, parent: 'users' } }});
Sample Users Appvar usersApp = new Y.App({ views: { users: { type : Y.UsersView, preserve: true },
user: { type : Y.UserView, parent: 'users' } }});
Sample Users Appvar usersApp = new Y.App({ views: { users: { type : Y.UsersView, preserve: true },
user: { type : Y.UserView, parent: 'users' } }});
Sample Users Appvar users = new Y.UsersList();
usersApp.route('/user/', function () { this.showView('users', {modelList: users});});
usersApp.route('/user/:id/', function (req) { var user = users.getById(req.params.id); this.showView('user', {model: user}, function (view) { // Called after transition. });});
Sample Users Appvar users = new Y.UsersList();
usersApp.route('/user/', function () { this.showView('users', {modelList: users});});
usersApp.route('/user/:id/', function (req) { var user = users.getById(req.params.id); this.showView('user', {model: user}, function (view) { // Called after transition. });});
Sample Users Appvar users = new Y.UsersList();
usersApp.route('/user/', function () { this.showView('users', {modelList: users});});
usersApp.route('/user/:id/', function (req) { var user = users.getById(req.params.id); this.showView('user', {model: user}, function (view) { // Called after transition. });});
Sample Users Appvar users = new Y.UsersList();
usersApp.route('/user/', function () { this.showView('users', {modelList: users});});
usersApp.route('/user/:id/', function (req) { var user = users.getById(req.params.id); this.showView('user', {model: user}, function (view) { // Called after transition. });});
Sample Users Appvar users = new Y.UsersList();
usersApp.route('/user/', function () { this.showView('users', {modelList: users});});
usersApp.route('/user/:id/', function (req) { var user = users.getById(req.params.id); this.showView('user', {model: user}, function (view) { // Called after transition. });});
Sample Users Appvar users = new Y.UsersList();
usersApp.route('/user/', function () { this.showView('users', {modelList: users});});
usersApp.route('/user/:id/', function (req) { var user = users.getById(req.params.id); this.showView('user', {model: user}, function (view) { // Called after transition. });});
Sample Users Appvar users = new Y.UsersList();
usersApp.route('/user/', function () { this.showView('users', {modelList: users});});
usersApp.route('/user/:id/', function (req) { var user = users.getById(req.params.id); this.showView('user', {model: user}, function (view) { // Called after transition. });});
Enhanced Navigation
Enhanced Navigation
pushState + Ajax = pjax
pushState + Ajax = pjax• Handles link clicks
• Update full URL
• Dynamically load & render content
• Ajax !=== XHR
• Browser’s Back/Forward buttons work!
• Seamless
Y.Router
Y.History
Y.PjaxBase
Y.Pjax
Y.Pjax
Server
Y.Pjax
Y.Pjax Mechanics
navigate()
XHR
link click DOM
setContent()
Recap Y.App• Is a View
• Is a Router
• Uses PjaxBase
• Has an activeView
• Manages View lifecycles & transitions
• Instantiate or sub-class
Templating
{{#with handlebars}}
Handlebars Templates<script id="entry-template" type="text/x-handlebars-template"> <div class="entry"> <h1><{{title}}</h1> {{#if author}} <p class="author">{{author}}</p> {{/if}} <div class="body">{{body}}</div> </div> </script>
Handlebars Templates<script id="entry-template" type="text/x-handlebars-template"> <div class="entry"> <h1><{{title}}</h1> {{#if author}} <p class="author">{{author}}</p> {{/if}} <div class="body">{{body}}</div> </div> </script>
Handlebars Templates<script id="entry-template" type="text/x-handlebars-template"> <div class="entry"> <h1><{{title}}</h1> {{#if author}} <p class="author">{{author}}</p> {{/if}} <div class="body">{{body}}</div> </div> </script>
Handlebars Templates<script id="entry-template" type="text/x-handlebars-template"> <div class="entry"> <h1><{{title}}</h1> {{#if author}} <p class="author">{{author}}</p> {{/if}} <div class="body">{{body}}</div> </div> </script>
Handlebars Templates<script id="entry-template" type="text/x-handlebars-template"> <div class="entry"> <h1><{{title}}</h1> {{#if author}} <p class="author">{{author}}</p> {{/if}} <div class="body">{{body}}</div> </div> </script>
Handlebars Templates<script id="entry-template" type="text/x-handlebars-template"> <div class="entry"> <h1><{{title}}</h1> {{#if author}} <p class="author">{{author}}</p> {{/if}} <div class="body">{{body}}</div> </div> </script>
Handlebars Templates<script id="entry-template" type="text/x-handlebars-template"> <div class="entry"> <h1><{{title}}</h1> {{#if author}} <p class="author">{{author}}</p> {{/if}} <div class="body">{{body}}</div> </div> </script>
Y.HandlebarsYUI().use('handlebars', 'node-base', function (Y) { var template = Y.one('#entry-template').getContent(), render = Y.Handlebars.compile(template), entry = { title : 'The Adventures of Tom Selleck', body : 'Tom crossed the river in his Ferrari…', author: 'Ryan Grove' }; Y.one('#entry').setContent(render(entry)); });
Y.HandlebarsYUI().use('handlebars', 'node-base', function (Y) { var template = Y.one('#entry-template').getContent(), render = Y.Handlebars.compile(template), entry = { title : 'The Adventures of Tom Selleck', body : 'Tom crossed the river in his Ferrari…', author: 'Ryan Grove' }; Y.one('#entry').setContent(render(entry)); });
Y.HandlebarsYUI().use('handlebars', 'node-base', function (Y) { var template = Y.one('#entry-template').getContent(), render = Y.Handlebars.compile(template), entry = { title : 'The Adventures of Tom Selleck', body : 'Tom crossed the river in his Ferrari…', author: 'Ryan Grove' }; Y.one('#entry').setContent(render(entry)); });
Y.HandlebarsYUI().use('handlebars', 'node-base', function (Y) { var template = Y.one('#entry-template').getContent(), render = Y.Handlebars.compile(template), entry = { title : 'The Adventures of Tom Selleck', body : 'Tom crossed the river in his Ferrari…', author: 'Ryan Grove' }; Y.one('#entry').setContent(render(entry)); });
Y.HandlebarsYUI().use('handlebars', 'node-base', function (Y) { var template = Y.one('#entry-template').getContent(), render = Y.Handlebars.compile(template), entry = { title : 'The Adventures of Tom Selleck', body : 'Tom crossed the river in his Ferrari…', author: 'Ryan Grove' }; Y.one('#entry').setContent(render(entry)); });
Y.HandlebarsYUI().use('handlebars', 'node-base', function (Y) { var template = Y.one('#entry-template').getContent(), render = Y.Handlebars.compile(template), entry = { title : 'The Adventures of Tom Selleck', body : 'Tom crossed the river in his Ferrari…', author: 'Ryan Grove' }; Y.one('#entry').setContent(render(entry)); });
Server-Side
Guides
Photos Near Me• Built with App Framework
• Uses Y.App and Y.Handlebars
• ~ 650 Lines of JavaScript
• Responsive Design
• http://photosnear.me
• https://github.com/ericf/photosnear.me
PhotosNearMe (Y.App)
Place (Y.Model)
Photos (Y.ModelList)
PhotosNearMe (Y.App)
GridView (Y.View)
PhotosNearMe (Y.App)
PhotosNearMe (Y.App)
Photo (Y.Model)
PhotosNearMe (Y.App)Place (Y.Model)
LightboxView (Y.View)
PhotosNearMe (Y.App)
Future…App Framework — 3.6.0+
Dealing with Data• Improved data access
• Model sync layers
• Data binding
Breadth & Depth• View extensions & plugins
• View-based widgets
• More mobile
• More server
Questions?Ask away!
Eric Ferraiuolo@ericf