JavaScript MVC Frameworks André de Santi Oliveira Frameworks • SproutCore • JavaScriptMVC • Backbone.js • • • • • • • • • • Knockout AngularJS PureMVC YUI 3 ActiveJS MooToolsMVC TrimJunction Jamal Claypool Spine Ecosystem Minification Frameworks ( YUI compressor JSMIN, … ) JavaScript MVC Framework ( SproutCore, JavaScriptMVC, Backbone.js, … ) Testing Frameworks (QUnit, Jasmine SinonJS, … ) JavaScript Frameworks ( jQuery, MooTools, YUI Library, Dojo Toolkit, …) Mobile Frameworks ( PhoneGap, Zepto, … ) Template Frameworks ( Mustache, JAML, Eco, ICanHaz.js, JQote 2, … ) Dynamic Stylesheet Language ( SASS, LESS ) Why MVC JavaScript ? • Front end developers know JavaScript • Better organization to front end applications • Abstract complexity • Good integration with JavaScript frameworks • An easier way to do tests Documentation • SproutCore: good documentation, examples, blog, mailing list, irc, videos at Vimeo. • JavaScriptMVC: excellent documentation, examples, blog, forum. • Backbone.js: documentation ok, mailing list, irc, videos at PeepCode. Architecture Client side DOM Server side view back end controller Model web services Responsibilities View • Binding DOM • Render templates • i18n Controller • Router • Initialize and create models • Manipulate DOM Model • Data Validation • Synchronize Data • Call web services Templates Frameworks SproutCore (cames with…) •Handlebars (mustache with more features) JavaScriptMVC (cames with…) •EJS •JAML •Micro •Mustache (2nd party plugin) Backbone.js (agnostic in this area) • • • • • • • JQueryUI ICanHaz.js PURE jQote Eco TrimPath KiTE Templates Frameworks Mustache mustache-jquery mustache-dojo mustache-yui mustache-commonjs var clients = { client: { name: ‘André de Santi Oliveira’, type: ‘VIP client’, domains: [{domain: ‘aso01.ca’}, {domain: ‘aso02.ca’}, {domain: ‘aso03.ca’}] } } {{#client}} <h1>{{name}}</h1> <b>{{type}}</b> <ul> {{#domains}} <li>{{domain}}</li> {{/domains}} </ul> {{/client}} <h1>André de Santi Oliveira<h1> <b>VIP client</b> <ul> <li>aso01.ca</li> <li>aso02.ca</li> <li>aso03.ca</li> </ul> Handlebars - Sproutcore hosts.handlebars {{#view MyApp.CreateHostView}} <input id="hostName" type="text" /> {{/view}} {{#collection SC.TemplateCollectionView contentBinding="MyApp.hostController” itemClassBinding="content"}} {{view MyApp.HostsView}} {{/collection}} View / Controller - SproutCore MyApp = SC.Application.create(); MyApp.CreateHostView = SC.TextField.extend({ insertNewLine: function() { var hostName = this.get('value'); MyApp.hostController.createHost(hostName); } }); MyApp.HostsView = SC.LabelView.extend({ valueBinding: '.parentView.content.name' }); MyApp.hostController = SC.ArrayController.create({ content: [], createHost: function(name){ var host = MyApp.Host.create({ name : name}); this.pushObject(host); host.save(); } SC.ready(function() { }); MyApp.mainPane = SC.TemplatePane.append({ templateName: 'hosts', }); }); Model - SproutCore MyApp.Host = SC.Object.extend({ id: null, name: null, attributes: function(){ return { id: this.get('id'), name: this.get('name') } }, save: function(){ $.ajax('/host', { type: 'POST', data: {host : this.get('attributes')}, dataType: 'json', success: function(data, response) { this.set('id', data['host','id']); } }); }, syncHost: function(){ var host = ... get new host from PushServer MyApp.hostController.pushObject(host); } }); Sync / Async load JavaScriptMVC The default is synchronous, but async is possible : $(‘#client-info’).html(‘templates/client-info.ejs’, data, function(result) { this.fadeIn(); }); Preload the template : $.get(‘templates/client-info.jaml’, {}, function(){}, ‘view’); SproutCore $.get(‘templates/client-info.handlebars', function(data) { var template = SC.Handlebars.compile(data); SC.TEMPLATES[’client-info'] = template; }) i18n SproutCore strings.js SC.StringsFor(‘fr_CA’, { ‘name’: ‘nom’ }); MyApp.TitleLabel = SC.LabelView.extend({ localize: YES, value: ‘name’ }); -MyApp/ -core.js -en/ strings.js style.css -images/ -welcome.png -fr/ strings.js style.css -images/ -bienvenue.png -main.js JavaScriptMVC and Backbone.js don’t offer native i18n. Router Backbone.js var Workspace = Backbone.Router.extend({ routes: { “domains/:domain”: “getdomain” }, getdomain: function(domain) { //refresh model and re-render the specific view } }); The router is the controller in Backbone.js Validation JavaScriptMVC $.Model.extend(“Client”,{ init : function(){ this.Validate(“name”, function(){ if(this.name == ‘’){ return ‘Name is required’ } }) } }, {}); • • • • • validateFormatOf validateInclusionOf validateLengthOf validatePresenceOf validateRangeOf Backbone.js var Client = Backbone.Model.extend({ validate: function(attrs) { if (attrs.name == ‘’) { return ‘Name is required’ } } }); Rest / SOAP Backbone.js Default CRUD implementation • create => POST => /client • read => GET => /client/[id] • update => PUT => /client/id • delete => DELETE => /client/id Using SOAP Backbone.emulateHTTP = true; model.save(); The Backbone.sync use (jQuery/Zepto).ajax Security CAS – Central Authentication Service • • mod_auth_cas Spring CAS web services Dynamic StyleSheet Language SASS LESS Variables Mixins $red: FF0000; .h1 { color: $red; } .h2 { color: darken($red, 10%); } Selector inheritance .error { border: 2px; background: $red; } .error.intrusion { font-weight: bold; } .badError { @extend .error; border-width: 5px; } .rounded-corners (@radius: 5px) { border-radius: @radius; } #header { .rounded-corners; } #footer { .rounded-corners(10px); } Nesting #header { h1 { font-size: 26px; font-weight: bold; } p { font-size: 12px; } } } Mobile Frameworks Backbone.js + PhoneGap $(function() { backbone.views.pages.Audio = Backbone.View.extend({ ... play : function(){ this.media().play(); return false; }, stop : function() { this.media().stop(); return false; } }); }); Tests Frameworks Backbone.js + Jasmine + Sinon.JS it("should make the correct server request", function() { var host = new Backbone.Model({ name: ”aso01.ca", url: "/client/hosts/1" }); var spy = sinon.spy(jQuery, 'ajax'); host.save(); expect(spy).toHaveBeenCalled(); expect(spy.getCall(0).args[0].url) .toEqual("/client/hosts/1"); jQuery.ajax.restore(); }); JavaScript Libraries Underscore.js Provides 60-odd functions : Collections(each, sortBy, size), Arrays(last, union, unique), Functions(bind, after, compose), Objects(clone, isFunction, isNull), etc Raphaël Simplify the work with vector graphics on the web. Uses the SVG W3C Recommendation and VML as a base for creating graphics. This means every graphical object you create is also a DOM object. StealJS A collection of command and browser based JavaScript utilities that make building, packaging, sharing, and consuming JavaScript applications easy. jQueryMX A collection of useful jQuery libraries that provide the missing functionality necessary to implement and organize large-scale jQuery applications Conclusion • Very useful to rich applications • Backend agnostic • Model => JSon => Model • JavaScript is a powerful language • Don’t you like JavaScript ? Try CoffeeScript ! Please, please, please !!! A hammer is an excellent tool, but it’s not used for everything !!! Watch and Listen InfoQ •Single Page Apps and the Future of History •Yehuda Katz Discusses SproutCore •Introduction to SproutCore •Doug Crockford on HTML and Fixing the Web •HTML5 and the Dawn of Rich Mobile Web Applications PeepCode •Backbone.js Basics •Backbone.js Interactivity blip.tv •blip.tv - JSConf 2011 JavaScript Podcast •The Javascript Show •yayQuery Books • JavaScript: The Good Parts • JavaScript Patterns • Pro JavaScript Design Patterns • Test-Driven JavaScript Development • Object-Oriented JavaScript: Create scalable, reusable high-quality JavaScript applications and libraries • High Performance JavaScript • Pro JavaScript Techniques References JavaScript MVC Frameworks •SproutCore (http://www.sproutcore.com/) •JavaScriptMVC (http://javascriptmvc.com/) •Backbone.js (http://...doccloud.../backbone/) Template Frameworks •Mustache (http://mustache.github.com/) •Handlebars (http://www.handlebarsjs.com/) •Jaml (http://edspencer.github.com/jaml/) JavaScript Frameworks •YUI (http://developer.yahoo.com/yui/) •DOJO (http://dojotoolkit.org/) •CommonJS (http://www.commonjs.org/) •jQueryUI (http://jqueryui.com/) Mobile Frameworks •PhoneGap (http://www.phonegap.com/) •Zepto.js (http://zeptojs.com/) •jQueryMobile (http://jquerymobile.com/) JavaScript Library •Underscore.js (http://...doccloud.../underscore/) •Raphaël (http://raphaeljs.com/) •StealJS (http://.../stealjs-script-manager) •jQueryMX (http://jquerymx.com/) JavaScript Tests Frameworks •jQuery QUnit (http://docs.jquery.com/Qunit/) •FuncUnit (http://funcunit.com/) •Jasmine (http://pivotal.github.com/jasmine/) •SinonJS (http://sinonjs.org/) Dynamic Stylesheet Language •SASS (http://sass-lang.com/) •LESS (http://lesscss.org/) Security •CAS (http://www.jasig.org/cas/) Thank you Merci