Ampersand.js

If there was a backbone 2.0, this would be it


Originally given as a
Lightning Talk
for @nebraskajs
by Mike Macaulay
@mmacaula

Agenda




What is it?

My Experiences

How you can start using it today




Backbone is great!


it's simple
un-opinionated





But...




Couple of pain points

Attempted to be solved by:

Marionette.js
Backbone Relational
ModelBinder
Sticket 
on and on... 




Enter Ampersand.js



What makes it different?


Node Inspired

Separate out Models, Views, Router

CommonJS format

NPM / Browserfy

ES5 Features

Lot's of nice features

Enough Already



Show me some code!

Backbone Model

/**  Person
*    firstname : string
*    lastname : string
**/
var Person = Backbone.Model.extend({
  getFullName : function(){
    return this.get('firstname') + ' ' + this.get('lastname');
  }
});

Introducing Ampersand State 

 var Person = AmpersandState.extend({
    props: {
        firstName: 'string',
        lastName: 'string'
    },
    session: {
        signedIn: ['boolean', true, false],
    },
    derived: {
        fullName: {
            deps: ['firstName', 'lastName'],
            fn: function () {
                return this.firstName + ' ' + this.lastName;
            }
        }
    }
}); 

PropertieS

 var Person = AmpersandState.extend({
props: { firstName: ['string', true, 'Billy'] lastName: {type:'string', required:false, default:'mac'} } }); var person = new Person({firstName : 'Mike'}); person.firstName = 'Mikey'; // or person.set('firstName','Mikey'); person.firstName = new Date() // throws error!

Session Properties

 var Person = AmpersandState.extend({
props: { // first and last name }, session : { signedIn : 'boolean' }  });
var person = new Person({});person.signedIn = true;person.toggle('signedIn'); // toggle!person.toJSON() // => // won't include signedIn

Derived Properties

var Person = AmpersandState.extend({
// first and last name 
 derived: {
  fullName: {
    deps: ['firstName', 'lastName'],
    fn: function () {
      return this.firstName + ' ' + this.lastName;
    }
  }
 }
});

var person = new Person();person.on('change:fullName', callback);

Plus much more



  • Child Models
  • Child Collections
  • Event Bubbling from children



Ampersand Views


Kind of like Backbone Super views...

Views


  • Automatic Model Binding
  • Always expects a template
  • Extends from Ampersand State
  • Can handle child views

Model Binding



 var PersonView = AmpersandView.extend({
    templates: templates.person,

    bindings: {
        'model.name': {
            type: 'text',
            hook: 'name'
        },

        'model.age': '[hook=age]', //shorthand of the above
    }
});  

A common Pattern

Template:
... <button class="save-button">Save</button>...
View Code:
var View = Backbone.View.extend({   events : {      'click .save-button' : 'onSave'   }});


Problem is...


I've now mixed up my css and javascript together.  

No one knows what can be changed


Using the Data-Hook Attribute

Template:
 <button data-hook="save" class="whatever-i-dont-care">Save</button>
Ampersand View:
var View = AmpersandView.extend({  events : {    'click [data-hook="save"]' : 'onSave'
  }});

Plus Much More



  • Cached Elements
  • SubView management
  • Form management 
  • View Switcher (a la marionette regions)



Still interested?


Much more than just Models and Views

Great API docs, good introduction pages at ampersandjs.com



Why I'm excited about it


Upgrade Path from Backbone

Solves many major pain points

Still Flexible

We're using it today!


From ampersand.js home page

My experience




Experience


Ampersand and Backbone live perfectly side by side

var MyAmpersandView  = require('path-to-ampersand-veiw');
 Marionette.Layout.extend({
  regions : {
      foo : "[data-region=foo]"
  },
  onRender : function(){
      this.foo.show(new MyAmpersandView());            // just works!
  }



Experience


So we took the plunge..

Replaced all our models with Ampersand Models

All new views are Ampersand views.  

We still like Marionette Layouts though...
so we keep using those. 

No problem either way.  

Ok, so how do i Use it?


You may have noticed...

npm / browserify

I use require.js.  Am I screwed?   




YES.

No, just kidding


It's relatively easy to bring ampersand into your require.js project.

Fully running example contributed by yours truly:  
https://github.com/AmpersandJS/examples

Final thoughts



Advantages of a loosely coupled architecture.

Using the best tool for the job.

Virtual Dom as an example.  




Questions?

Made with Slides.com