SlideShare a Scribd company logo
SPINE JS
var Messenger = function(message){
  defaultGreeting = "hello ";
  this.message = message;
}

Messenger.prototype.sayHi = function(){
  alert(defaultGreeting + this.message);
}

var hiDosug = new Messenger("DOSUG");
hiDosug.sayHi();
tr    var Messenger = function(message){
                                              ("id",
            listParent.children("ul").at
"list" + uniqueListId);                          defaultGreeting = "hello ";

              self.listName = "list" +
                                    listParent = $  this.message = message;
uniqueLi stId;         ('#categoryList').pare
                                                nt();
                                                  }
                                                 " +
              li stParent.attr("id", "wrapper            var
                                    listParent.children("u ViewBuilder = functi
                                                             l").attr("id",       on(type){
uniqueListId);         "list" + uniqueListId); Messenger.prototype.sayHi = functionunction(){
                                                           defaultSomething = "grid"
              se lf.wrapperName = self pper" +
                                     "wra                                             ;
                                         .listName alert(defaultGreeting + this.message);
                                                    = "list" +
uniqueLi stId;         uniqueListId;                       this.type = type;
                   this.message = message;
                                               , } ue);
                                                  tr
               self.updateView(inlistPa tion
                                    Transi
                                           rent.attr("id",this.buildView();
                                                             "wrapper" +
                }     uniqueListId);      listParent = $
                                                  var hiDosug = new Messenger("DOSUG");
           })               ('#categoryList').parent(); }
                Messenger.prototype.sayHi = function(){
                                   self.wrapperName = "wra
                                                  hiDosug.sayHi(); +
                                                              pper"
       );             uniqueListId;       listParent.children("ul").attr("id",
                                                        Messen
                   alert(defaultGreeting + this.message); ger.prototype.buildView = function(
                            "list" + uniqueListId);
 }switch(this.viewType){           self.updateView(inTran target.loa
                                                          $( tion, true 'templates
                }                                           si          d();        /category.html'
                                          self.listName = "list" +
      case "grid":          uniqueListId;
                               })
                var hiDosug = new Messenger("DOSUG");             function() {
        templatePath = "templates/ listParent.attr("id", "wrapper" +
                            );
  categoryGridElement.html";
                hiDosug.sayHi();                                     listParent = $
                            uniqueListId);             ('#categoryList').parent
                     }                                                           ();
        break;                            self.wrapperName = "wrapper" +
                                                                     listParent.children("ul"
                            uniqueListId;              "list" + uniqueListId);                ).att
      default:
                                          self.updateView(inTransition, true);
        templatePath = "templates/                                  self.listName = "list" +
                                                       uniqueListId;
  categoryListElement.html";          })

    }                                                            listParent.attr("id", "w
                                                                                          rapper
What’s Needed


Framework for consistency

Core UI and Data Modeling

Easy to get up to speed

Minimal dependencies
What’s Out There
SPINE JS HISTORY
MAY 2011
OCTOBER 2011
CURRENT V1.0.4 5
JAVASCRIPT OR
COFFESCRIPT
CoffeeScript


You’re not forced into using it

SpineJS is written in CoffeeScript

It’s not just a cool new trend...
CoffeeScript Benefits


Helps avoid erroneously global vars and pollution

Leads to more readable code

Provides appearance of classical inheritance
WHAT’S IN IT FOR ME?
Benefits


Lightweight Framework

Single Library Dependency

Straightforward Use
More reasons...


Flexible UI rendering with no pre-determined templating

Built in LocalStorage and RESTful support

Write once with near-ready-to-deploy mobile code
Minimal Dependencies
Compatibility


No Plans for Archaic Browser Support

HTML5-Centric with LocalStorage

json2.js Dependency for IE7 Support
ON THE HORIZON
Spine Mobile


Strengthens reason to build around core framework

Extend core components to be mobile ready

Requires minimal additional implementation
Spine Mobile


No Re-Writing, Extend Existing Controllers

Transition Effects

Tap & Orientation Events
IMPLEMENTATION
& CODE EXAMPLES
SPINE CLASS
Module (a.k.a. Spine Class)


Spine’s extension of core CoffeeScript class

Provides class and instance property support

All Spine internals inherit from Spine.Module
Spine Module
   (a.k.a. Extended CoffeeScript Class)


class MyClass extends Spine.Module
  @extend MyOtherClass
  @include myInstanceProperty
MODEL
Model


Inherits from Spine.Module

Establishes Controller and UI Agnostic Data Model

One and Only component for storing and retrieving data
(local or remote)
class UsrGrp extends Spine.model
   @configure "UsrGrp",
   ↳"groupName", "description"


   @extend Spine.Model.Ajax
   @extend Spine.Model.Local
class UsrGrp extends Spine.model
   @configure "UsrGrp",
   ↳"groupName", "description"


   @extend Spine.Model.Ajax
   @extend Spine.Model.Local


   validate: ->
      unless @groupName.length > 0
      "Group Name field missing"
@extend Spine.Model.Ajax
@extend Spine.Model.Local


validate: ->
   unless @groupName.length > 0
   "Group Name field missing"
CONTROLLER
Controller


Brings it all together

Glues the HTML, DOM manipulation and Model together

Handles all event and UI interaction binding

Extends Spine.Events, allows custom event triggering
class UsrGrpsApp extends
   ↳Spine.Controller
   constructor: ->
      super
      UsrGrp.bind("create",
      ↳@addOne)


   #Bind event handling
UsrGrp.bind("create",
   ↳@addOne)


#Bind event handling
#to DOM elements
events:
   "submit form": "create"
   "click .deleteAll": "delete"


#DOM Element references
elements:
events:
   "submit form": "create"
   "click .deleteAll": "delete"


#DOM Element references
elements:
  "form input": "input"
  ".list": "list"


#New up a model & render
create: (event) ->
"form input": "input"
  ".list": "list"


#New up a model & render
create: (event) ->
   #Prevent form submit
   #page load from propagating
   event.preventDefault()


   #New up a model instance
#Prevent form submit
#page load from propagating
event.preventDefault()


#New up a model instance
user = new UserGrp(
↳groupName: @input.val())


#Persist or catch
#validation error
unless user.save()
user = new UserGrp(
  ↳groupName: @input.val())


   #Persist or catch
   #validation error
   unless user.save()
      #Very basic notification
      alert user.validate()


#Add new element to DOM
#Add new element to DOM
#Triggered on create() of Model
addOne: (userGroup) =>
   group = new UsrGrps(
  ↳item: userGroup)
   @list.append(
  ↳$("#listTemplate")
  ↳.tmpl(userGroup))
GETTING IT STARTED
$ = jQuery
$ ->
  new UsrGrpsApp(el: $("#groups"))
CONTROLLER MANAGER
Controller Manager


Simple state machine for Controller Instances

One additional script to include in HTML

Manipulates DOM with class flag
<script src="lib/spine/manager.js"
↳type="text/javascript"></script>
class UsrGrpsApp extends
↳Spine.Controller
class OtherController extends
↳Spine.Controller


ugApp = new UsrGrpsApp
other = new OtherController
class UsrGrpsApp extends
↳Spine.Controller
class OtherController extends
↳Spine.Controller


ugApp = new UsrGrpsApp
other = new OtherController


new Spine.Manager(ugApp, other)
class OtherController extends
↳Spine.Controller


ugApp = new UsrGrpsApp
other = new OtherController


new Spine.Manager(ugApp, other)
ugApp.active()
Ques
    tions
         ?
Contact Me

Jordan McCullough
Twitter: @ambientphoto
Email: jordanm@ambientideas.com
Web: ambientideas.com
Links & Resources

SpineJS: http://www.SpineJS.com

jQuery: http://www.jQuery.com

Zepto: http://www.ZeptoJS.com

CoffeeScript: http://jashkenas.github.com/coffee-script/

Little Book of CoffeeScript:
http://arcturo.github.com/library/coffeescript/
Links & Resources


JavaScriptMVC: http://javascriptmvc.com

Backbone JS: http://documentcloud.github.com/backbone/

SproutCore: http://www.sproutcore.com

Knockout: http://knockoutjs.com
Photo Credit



Ambient Ideas Photography
http://www.AmbientIdeasPhotography.com

More Related Content

KEY
Grails UI Primer
PDF
Programa simulacion de ventas de aeropuerto
PDF
Object Calisthenics Adapted for PHP
KEY
Building a Pluggable Plugin
PDF
Erlang for data ops
PDF
Functionality Focused Code Organization
KEY
ddd+scala
PDF
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf
Grails UI Primer
Programa simulacion de ventas de aeropuerto
Object Calisthenics Adapted for PHP
Building a Pluggable Plugin
Erlang for data ops
Functionality Focused Code Organization
ddd+scala
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHPKonf

What's hot (20)

PDF
From mysql to MongoDB(MongoDB2011北京交流会)
PDF
Advanced MongoDB #1
PDF
Modern Application Foundations: Underscore and Twitter Bootstrap
PDF
2013-03-23 - NoSQL Spartakiade
PDF
Doctrine MongoDB Object Document Mapper
PDF
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHP Yo...
PDF
Dig Deeper into WordPress - WD Meetup Cairo
PDF
ZendCon2010 Doctrine MongoDB ODM
PDF
Symfony2 from the Trenches
PDF
Using Templates to Achieve Awesomer Architecture
PDF
Symfony Day 2010 Doctrine MongoDB ODM
PDF
droidQuery: The Android port of jQuery
PPTX
Object oriented javascript
PPTX
Ch8(oop)
PDF
Services Drupalcamp Stockholm 2009
PDF
Cleaner, Leaner, Meaner: Refactoring your jQuery
PDF
Dependency Injection
PDF
RxSwift 시작하기
PDF
Spock and Geb
From mysql to MongoDB(MongoDB2011北京交流会)
Advanced MongoDB #1
Modern Application Foundations: Underscore and Twitter Bootstrap
2013-03-23 - NoSQL Spartakiade
Doctrine MongoDB Object Document Mapper
“Writing code that lasts” … or writing code you won’t hate tomorrow. - PHP Yo...
Dig Deeper into WordPress - WD Meetup Cairo
ZendCon2010 Doctrine MongoDB ODM
Symfony2 from the Trenches
Using Templates to Achieve Awesomer Architecture
Symfony Day 2010 Doctrine MongoDB ODM
droidQuery: The Android port of jQuery
Object oriented javascript
Ch8(oop)
Services Drupalcamp Stockholm 2009
Cleaner, Leaner, Meaner: Refactoring your jQuery
Dependency Injection
RxSwift 시작하기
Spock and Geb
Ad

Similar to Spine JS (20)

PPTX
Taming that client side mess with Backbone.js
PDF
The City Bars App with Sencha Touch 2
PDF
After max+phonegap
PDF
混搭移动开发:PhoneGap+JQurey+Dreamweaver
KEY
MVC on the server and on the client
PDF
MVC on the Server and on the Client: How to Integrate Spring MVC and Backbone...
KEY
User Interface Development with jQuery
PDF
Internal DSLs
PDF
Ria with dojo
PDF
Ember.js - A JavaScript framework for creating ambitious web applications
PDF
Backbone.js: Run your Application Inside The Browser
PDF
Organizing Code with JavascriptMVC
PDF
Client-side MVC with Backbone.js
PDF
Client-side MVC with Backbone.js (reloaded)
PDF
JavaScript Libraries Overview
KEY
Juicer javascript template engine
PDF
Building a Mobile App with Sencha Touch
PDF
Deep Dive into Backbone.js Internals + Underscore.js
KEY
Backbone.js Simple Tutorial
PDF
Single Page Applications in Angular (italiano)
Taming that client side mess with Backbone.js
The City Bars App with Sencha Touch 2
After max+phonegap
混搭移动开发:PhoneGap+JQurey+Dreamweaver
MVC on the server and on the client
MVC on the Server and on the Client: How to Integrate Spring MVC and Backbone...
User Interface Development with jQuery
Internal DSLs
Ria with dojo
Ember.js - A JavaScript framework for creating ambitious web applications
Backbone.js: Run your Application Inside The Browser
Organizing Code with JavascriptMVC
Client-side MVC with Backbone.js
Client-side MVC with Backbone.js (reloaded)
JavaScript Libraries Overview
Juicer javascript template engine
Building a Mobile App with Sencha Touch
Deep Dive into Backbone.js Internals + Underscore.js
Backbone.js Simple Tutorial
Single Page Applications in Angular (italiano)
Ad

Recently uploaded (20)

PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PPTX
Spectroscopy.pptx food analysis technology
PDF
Encapsulation_ Review paper, used for researhc scholars
PDF
Encapsulation theory and applications.pdf
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PDF
Empathic Computing: Creating Shared Understanding
PPTX
Cloud computing and distributed systems.
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
PDF
cuic standard and advanced reporting.pdf
PPTX
Understanding_Digital_Forensics_Presentation.pptx
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
DOCX
The AUB Centre for AI in Media Proposal.docx
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PDF
Network Security Unit 5.pdf for BCA BBA.
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Spectroscopy.pptx food analysis technology
Encapsulation_ Review paper, used for researhc scholars
Encapsulation theory and applications.pdf
The Rise and Fall of 3GPP – Time for a Sabbatical?
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
Empathic Computing: Creating Shared Understanding
Cloud computing and distributed systems.
Unlocking AI with Model Context Protocol (MCP)
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
cuic standard and advanced reporting.pdf
Understanding_Digital_Forensics_Presentation.pptx
Diabetes mellitus diagnosis method based random forest with bat algorithm
The AUB Centre for AI in Media Proposal.docx
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
Building Integrated photovoltaic BIPV_UPV.pdf
Network Security Unit 5.pdf for BCA BBA.
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy

Spine JS

  • 2. var Messenger = function(message){ defaultGreeting = "hello "; this.message = message; } Messenger.prototype.sayHi = function(){ alert(defaultGreeting + this.message); } var hiDosug = new Messenger("DOSUG"); hiDosug.sayHi();
  • 3. tr var Messenger = function(message){ ("id", listParent.children("ul").at "list" + uniqueListId); defaultGreeting = "hello "; self.listName = "list" + listParent = $ this.message = message; uniqueLi stId; ('#categoryList').pare nt(); } " + li stParent.attr("id", "wrapper var listParent.children("u ViewBuilder = functi l").attr("id", on(type){ uniqueListId); "list" + uniqueListId); Messenger.prototype.sayHi = functionunction(){ defaultSomething = "grid" se lf.wrapperName = self pper" + "wra ; .listName alert(defaultGreeting + this.message); = "list" + uniqueLi stId; uniqueListId; this.type = type; this.message = message; , } ue); tr self.updateView(inlistPa tion Transi rent.attr("id",this.buildView(); "wrapper" + } uniqueListId); listParent = $ var hiDosug = new Messenger("DOSUG"); }) ('#categoryList').parent(); } Messenger.prototype.sayHi = function(){ self.wrapperName = "wra hiDosug.sayHi(); + pper" ); uniqueListId; listParent.children("ul").attr("id", Messen alert(defaultGreeting + this.message); ger.prototype.buildView = function( "list" + uniqueListId); }switch(this.viewType){ self.updateView(inTran target.loa $( tion, true 'templates } si d(); /category.html' self.listName = "list" + case "grid": uniqueListId; }) var hiDosug = new Messenger("DOSUG"); function() { templatePath = "templates/ listParent.attr("id", "wrapper" + ); categoryGridElement.html"; hiDosug.sayHi(); listParent = $ uniqueListId); ('#categoryList').parent } (); break; self.wrapperName = "wrapper" + listParent.children("ul" uniqueListId; "list" + uniqueListId); ).att default: self.updateView(inTransition, true); templatePath = "templates/ self.listName = "list" + uniqueListId; categoryListElement.html"; }) } listParent.attr("id", "w rapper
  • 4. What’s Needed Framework for consistency Core UI and Data Modeling Easy to get up to speed Minimal dependencies
  • 11. CoffeeScript You’re not forced into using it SpineJS is written in CoffeeScript It’s not just a cool new trend...
  • 12. CoffeeScript Benefits Helps avoid erroneously global vars and pollution Leads to more readable code Provides appearance of classical inheritance
  • 13. WHAT’S IN IT FOR ME?
  • 14. Benefits Lightweight Framework Single Library Dependency Straightforward Use
  • 15. More reasons... Flexible UI rendering with no pre-determined templating Built in LocalStorage and RESTful support Write once with near-ready-to-deploy mobile code
  • 17. Compatibility No Plans for Archaic Browser Support HTML5-Centric with LocalStorage json2.js Dependency for IE7 Support
  • 19. Spine Mobile Strengthens reason to build around core framework Extend core components to be mobile ready Requires minimal additional implementation
  • 20. Spine Mobile No Re-Writing, Extend Existing Controllers Transition Effects Tap & Orientation Events
  • 23. Module (a.k.a. Spine Class) Spine’s extension of core CoffeeScript class Provides class and instance property support All Spine internals inherit from Spine.Module
  • 24. Spine Module (a.k.a. Extended CoffeeScript Class) class MyClass extends Spine.Module @extend MyOtherClass @include myInstanceProperty
  • 25. MODEL
  • 26. Model Inherits from Spine.Module Establishes Controller and UI Agnostic Data Model One and Only component for storing and retrieving data (local or remote)
  • 27. class UsrGrp extends Spine.model @configure "UsrGrp", ↳"groupName", "description" @extend Spine.Model.Ajax @extend Spine.Model.Local
  • 28. class UsrGrp extends Spine.model @configure "UsrGrp", ↳"groupName", "description" @extend Spine.Model.Ajax @extend Spine.Model.Local validate: -> unless @groupName.length > 0 "Group Name field missing"
  • 29. @extend Spine.Model.Ajax @extend Spine.Model.Local validate: -> unless @groupName.length > 0 "Group Name field missing"
  • 31. Controller Brings it all together Glues the HTML, DOM manipulation and Model together Handles all event and UI interaction binding Extends Spine.Events, allows custom event triggering
  • 32. class UsrGrpsApp extends ↳Spine.Controller constructor: -> super UsrGrp.bind("create", ↳@addOne) #Bind event handling
  • 33. UsrGrp.bind("create", ↳@addOne) #Bind event handling #to DOM elements events: "submit form": "create" "click .deleteAll": "delete" #DOM Element references elements:
  • 34. events: "submit form": "create" "click .deleteAll": "delete" #DOM Element references elements: "form input": "input" ".list": "list" #New up a model & render create: (event) ->
  • 35. "form input": "input" ".list": "list" #New up a model & render create: (event) -> #Prevent form submit #page load from propagating event.preventDefault() #New up a model instance
  • 36. #Prevent form submit #page load from propagating event.preventDefault() #New up a model instance user = new UserGrp( ↳groupName: @input.val()) #Persist or catch #validation error unless user.save()
  • 37. user = new UserGrp( ↳groupName: @input.val()) #Persist or catch #validation error unless user.save() #Very basic notification alert user.validate() #Add new element to DOM
  • 38. #Add new element to DOM #Triggered on create() of Model addOne: (userGroup) => group = new UsrGrps( ↳item: userGroup) @list.append( ↳$("#listTemplate") ↳.tmpl(userGroup))
  • 40. $ = jQuery $ -> new UsrGrpsApp(el: $("#groups"))
  • 42. Controller Manager Simple state machine for Controller Instances One additional script to include in HTML Manipulates DOM with class flag
  • 44. class UsrGrpsApp extends ↳Spine.Controller class OtherController extends ↳Spine.Controller ugApp = new UsrGrpsApp other = new OtherController
  • 45. class UsrGrpsApp extends ↳Spine.Controller class OtherController extends ↳Spine.Controller ugApp = new UsrGrpsApp other = new OtherController new Spine.Manager(ugApp, other)
  • 46. class OtherController extends ↳Spine.Controller ugApp = new UsrGrpsApp other = new OtherController new Spine.Manager(ugApp, other)
  • 48. Ques tions ?
  • 49. Contact Me Jordan McCullough Twitter: @ambientphoto Email: jordanm@ambientideas.com Web: ambientideas.com
  • 50. Links & Resources SpineJS: http://www.SpineJS.com jQuery: http://www.jQuery.com Zepto: http://www.ZeptoJS.com CoffeeScript: http://jashkenas.github.com/coffee-script/ Little Book of CoffeeScript: http://arcturo.github.com/library/coffeescript/
  • 51. Links & Resources JavaScriptMVC: http://javascriptmvc.com Backbone JS: http://documentcloud.github.com/backbone/ SproutCore: http://www.sproutcore.com Knockout: http://knockoutjs.com
  • 52. Photo Credit Ambient Ideas Photography http://www.AmbientIdeasPhotography.com