ampersandjs

67
@drewfyock Ampersand.js Minimalistic Approach to not so minimalistic problems

Upload: drew-fyock

Post on 14-Jul-2015

137 views

Category:

Software


0 download

TRANSCRIPT

@drewfyock

Ampersand.jsMinimalistic Approach

to not so minimalistic problems

@drewfyock

Ampersand.jsby

@drewfyock

Core Team

@henrikjoreteg@philip_roberts @lancestout @lynnandtonic

@lukekarrys @wraithgar @kamilogorek

@drewfyock

Community Team

@bear@drewfyock @aaronmccall

@remko @fox @mmacaula

@drewfyock

Overview

@drewfyock

@drewfyock

State

ampersand-state

@drewfyock

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;

}

}

}

});

@drewfyock

Models

ampersand-modelampersand-state & ampersand-sync

@drewfyock

Collections

@drewfyock

ampersand-collection / ampersand-subcollection / ampersand-rest-collection

ampersand-collection

@drewfyock

ampersand-subcollectionampersand-collection & ampersand-collection-underscore-mixin

@drewfyock

var WidgetCollection = require('./mycollection');

var SubCollection = require('ampersand-subcollection');

var widgets = new WidgetCollection();

widgets.fetch();

var favoriteWidgets = new SubCollection(widgets, {

where: {

awesome: true

},

comparator: function (model) {

return model.rating;

}

});

@drewfyock

ampersand-rest-collectionampersand-collection & ampersand-collection-rest-mixin & ampersand-collection-underscore-mixing

@drewfyock

Views

@drewfyock

ampersand-viewampersand-state & ampersand-collection-view & ampersand-dom-bindings

@drewfyock

var PersonRowView = AmpersandView.extend({

template: "<li><span data-hook='name'></span><span data-hook='age'></span><a data-

hook='edit'>edit</a></li>",

events: {

"click [data-hook=edit]": "edit"

},

bindings: {

"model.name": {

type: 'text',

hook: 'name'

},

"model.age": {

type: 'text',

hook: 'age'

}

},

subviews: {

personSubview: {...}

},

edit: function () {...}

});

@drewfyock

ampersand-view-switcherampersand-view

@drewfyock

var pageSwitcher = new ViewSwitcher(pageContainer, {

waitForRemove: true,

hide: function (oldView, newView, cb) {

oldView.el.classList.add('animateOut');

setTimeout(cb, 1000);

},

show: function (newView, oldView) {

document.title = newView.pageTitle || 'app name';

document.body.scrollTop = 0;

app.currentPage = newView;

newView.el.classList.add('animateIn');

}

});

@drewfyock

ampersand-form-viewampersand-view

@drewfyock

var FormView = require('ampersand-form-view');

var InputView = require('ampersand-input-view');

var AwesomeFormView = new FormView({

submitCallback: function (obj) {

console.log('form submitted! Your data:', obj);

},

validCallback: function (valid) {

if (valid) {

console.log('The form is valid!');

} else {

console.log('The form is not valid!');

}

},

fields: [

new InputView({

name: 'client_name',

label: 'App Name',

placeholder: 'My Awesome App',

value: 'hello',

tests: [

function (val) {

if (val.length < 5) return "Must be 5+ characters.";

}

]

})

]

});

@drewfyock

ampersand-input-viewampersand-array-input-view

@drewfyock

ampersand-select-viewampersand-checkbox-view

@drewfyock

View Bindings

ampersand-dom-bindingsampersand-dom

@drewfyock

text

@drewfyock

text

class

@drewfyock

text

class

attribute

@drewfyock

text

class

attribute

value

@drewfyock

text

class

attribute

value

booleanClass

@drewfyock

text

class

attribute

value

booleanClass

booleanAttribute

@drewfyock

text

class

attribute

value

booleanClass

booleanAttribute

toggle

@drewfyock

text

class

attribute

value

booleanClass

booleanAttribute

toggle

switch

@drewfyock

text

class

attribute

value

booleanClass

booleanAttribute

toggle

switch

innerHTML

@drewfyock

var View = require('ampersand-view');

var templates = require(‘../templates’);

module.exports = View.extend({

template: templates.includes.person,

bindings: {

'model.fullName': '[data-hook=name]',

'model.avatar': {

type: 'attribute',

hook: 'avatar',

name: 'src'

},

'model.editUrl': {

type: 'attribute',

hook: ‘action-edit',

name: 'href'

},

'model.viewUrl': {

type: 'attribute',

hook: 'name',

name: 'href'

}

},

events: {

'click [data-hook=action-delete]': 'handleRemoveClick'

},

handleRemoveClick: function () {

this.model.destroy();

}

});

@drewfyock

Router

@drewfyock

var AppRouter = AmpersandRouter.extend({

routes: {

"help": "help", // #help

"search/:query":"search", // #search/kiwis

"search/:query/p:page": "search" // #search/kiwis/p7

},

help: function() {...},

search: function(query, page) {...}

});

@drewfyock

Mixins

ampersand-class-extend

@drewfyock

ampersand-collection-rest-mixin

@drewfyock

ampersand-collection-rest-mixin

ampersand-collection-underscore-mixin

@drewfyock

ampersand-collection-rest-mixin

ampersand-collection-underscore-mixin

ampersand-domthing-mixin

@drewfyock

ampersand-collection-rest-mixin

ampersand-collection-underscore-mixin

ampersand-domthing-mixin

ampersand-react-mixin

@drewfyock

Ampersand CLI

@drewfyock

Starting a new app

@drewfyock

Starting a new app

Generating form, view, model or collection

@drewfyock

Starting a new app

Generating form, view, model or collection

Generating models from JSON

@drewfyock

Starting a new app

Generating form, view, model or collection

Generating models from JSON

Generating forms from models

@drewfyock

Starting a new app

Generating form, view, model or collection

Generating models from JSON

Generating forms from models

Configuring the generated code

@drewfyock

// .ampersandrc

{

// default framework to be prompted with, options are express or hapi

framework: 'hapi',

indent: 4,

view: '', // default template

router: '', // default template

model: '', // default template

page: '', // default template

collection: '', // default template

clientfolder: 'client',

viewfolder: 'views',

pagefolder: 'pages',

modelfolder: 'models',

formsfolder: 'forms',

collectionfolder: 'models',

// whether to create collection when making a model

makecollection: true,

// if it was called without the 'gen' argument we're building a new one

// so we won't look for an application root

approot: '', // starts walking up folders looking for package.json

f: false, // overwrite

force: false, // overwrite flag, longform

quotes: 'single' // can be 'single' or 'double'

};

@drewfyock

Philosophy

@drewfyock

"Optimize for change,

it's the only constant."@HenrikJoreteg

10 Sep 2014

@drewfyock

It's not about

solving a problem,

it's about how you

approach it

@drewfyock

Vendor lock-in

@drewfyock

It's easier to learn only things you need to know

@drewfyock

Everythingis a

separate commonjs

module

@drewfyock

Everythingis

hosted on npm

@drewfyock

Everythingshould be

fully tested

@drewfyock

Everythinghas a

separate git repowith

separate git issues

@drewfyock

@drewfyock

Everythingdoes just

one thingand does it

well

@drewfyock

Leverage existing solutions

and

don't reinvent the wheel

@drewfyock

@drewfyock

Live demo

@drewfyock

Summary

@drewfyock

Why we chose Ampersand at Bessemer:

CommonJS by default

Flexible and modular

Based on Backbone

Just the right amount of magic

Incredibly easy to integrate with Express or Hapi

Support on Gitter

@drewfyock

Why you might not choose Ampersand:

Still fairly new

Moonboots - Jade

Not as “full featured" as Angular or Ember

May have to roll-your-own for specific components

@drewfyock

http://ampersandjs.com/contribute

http://issues.ampersandjs.com

https://github.com/ampersandjs

@drewfyock

Thank You@drewfyock @mikesabatini

http://bessemeralliance.com