Open Source Education



Open Source Education

0 0


reveal-temp


On Github iamchrismiller / reveal-temp

Open Source Education

Writing JavaScriptWeb Applications

Establishing a Baseline

Find and solve a problem once

Implement it everywhere

An example is Hello World, we're going to write a Todo app

The classic

Todo List

is an excellent choice

What makes up aTodo List?

A Todo Item
A Todo item A view into a list of items
A Todo item A view into a list of items A way to enter new Todo items
A Todo item A view into a list of items A way to enter new Todo items The ability to check off items
A Todo item A view into a list of items A way to enter new Todo items The ability to check off items A way to clear all completed items

Why a Todo List?

A Todo List requires

  • CRUD methods
  • Data Models
  • Collections/Lists
  • Views of different states
  • User interaction
  • Persistence

(Also)

www.todomvc.com

16 frameworks

All implementing the sameconcept with the same design

* Plus 30 more in the labs!

Moving to intro next

Our weapons

  • RequireJS
  • Backbone
  • Marionette

In a war against bloated files and endless script tags.

RequireJS

stands tall

How do you organize your code now?

Namespaces?

var yourblog = {
  account  : {},
  posts    : [],
  comments : []
}

Namespaces?

// yourblog.js
var yourblog = {}
// account.js
yourblog.account  = { stuff : {} }
// posts.js
yourblog.posts    = { moreStuff : {} }
// comments.js
yourblog.comments = { blech : {} }

Globally Accessible Modules?

<script src="Module1.js"></script>
<script src="Module2.js"></script>
<script src="Module3.js"></script>
<script src="app.js"></script>

Globally Accessible Modules?

<script src="Module1.js"></script>
<script src="Module2.js"></script>
<script src="Module3.js"></script>
<script src="Module4.js"></script>
<script src="Module5.js"></script>
<script src="Module6.js"></script>
<script src="Module7.js"></script>
<script src="Module8.js"></script>
<script src="Module9.js"></script>
<script src="Module10.js"></script>
<script src="Module11.js"></script>
<script src="Module12.js"></script>
<script src="app.js"></script>

Globally Accessible Modules?

<script src="Module1.js"></script>
<script src="Module2.js"></script>
<script src="Module3.js"></script>
<script src="Module4.js"></script>
<script src="Module5.js"></script>
<script src="Module12.js"></script> <!-- want to use 6 in 12? -->
<script src="Module6.js"></script>
<script src="Module7.js"></script>
<script src="Module8.js"></script>
<script src="Module9.js"></script>
<script src="Module10.js"></script>
<script src="Module11.js"></script>
<script src="app.js"></script>

Globally Accessible Modules?

<script src="Module1.js"></script>
<script src="Module2.js"></script>
<script src="Module3.js"></script>
<script src="Module4.js"></script>
<script src="Module9.js"></script> <!-- Did 9 depend on 12? -->
<script src="Module5.js"></script>
<script src="Module12.js"></script> <!-- 12 -->
<script src="Module6.js"></script>
<script src="Module7.js"></script>
<script src="Module8.js"></script>
<script src="Module10.js"></script>
<script src="Module11.js"></script>
<script src="app.js"></script>

One massive fileand your memory?

// Ha, just kidding.
// Right?

It's a balance...

You are burdened the more modular your code gets

Mo' scriptsMo' problems

AMD

Asynchronous Module Definition

AsynchronousModuleDefinition

  • AMD is not a library
  • AMD is a specification

With AMD you can...

  • Define async modules
  • Define fine grained dependencies
  • Develop without a build step
  • And a lot more

AMD at its core...

The specification defines a single function "define" that is available as a free variable or a global variable.

define()

define(id?, dependencies?, factory);

For example, myModule.js

define(['yourModule'], function(yourModule){
  // You are in a module called 'myModule'
  // That depends on and is provided 'yourModule'
});

AMD defines how to write modules

Not how to load or use them

RequireJS

requirejs.org

require(['dependency'],function(dependency) {
  // your module
);

curl

github.com/cujojs/curl

curl(['js!nonAMD.js'])
  .next(['dep1', 'dep2'], function (dep1, dep2) {
    // execute this phase
  })
  .next(['dep3'])
  .then(function () {
    // Execute when everything is ready
  });

Why use RequireJS?

Personal experience.It's a trusty workhorse.

Don't let that be your reason. Make your own.

Using RequireJS

<html>
  <head>
    <script data-main="scripts/main.js"
            src="scripts/vendor/require.js"></script>
  </head>
  <body>
  </body>
</html>

main.js

require(['dep1','dep2'],function(dep1,dep2){
  // And away we go!
})

There is more to AMDand RequireJS

But you can add that to your homework

Backbone.js

backbonejs.org

Backbone.js gives structure to web applications by providing models with key-value binding and custom events, collections with a rich API of enumerable functions, views with declarative event handling, and connects it all to your existing API over a RESTful JSON interface.

documentcloud

BackboneJS

Data First

Data Second

Backbone Models

Your Data

Your Data is gospel

Without your data, your app is nothing

Your data = bits of stuff

Models=Stuff

Remember

Your data is gospel

How do you treat it now?

Models are the heart of any JavaScript application, containing the interactive data as well as a large part of the logic surrounding it: conversions, validations, computed properties, and access control.

extend()

Backbone.Model.extend(properties [, classProperties]);

Model Attributes

var Person = Backbone.Model.extend({
  fullName : function() {
    return this.get('fName') + ' ' + this.get('lName');
  }
});

var cartoonist = new Person();

cartoonist.set('fName', 'Gary');
cartoonist.set('lName', 'Larson');

console.log(cartoonist.fullName());

Backbone Events

Event support

model.on(event, callback [, context])
model.off([event] [, callback] [, context])
model.trigger(event [, *args])

Built-in Events

  • add (model, collection)
  • remove (model, collection)
  • reset (collection)
  • change (model)
  • change:[attribute] (model)
  • destroy (model, collection)
  • sync (model, collection)
  • error (model, collection)
  • route:[name] (router)
  • all

Backbone Sync

A method convention for interacting with data storage

model.save()
model.fetch()
model.destroy()
// all delegate to
model.sync();

Backbone Collections

Collections=

lists of Stuff

Collections

Simple syntactic sugararound managing data

Syntax

var User = Backbone.Model.extend({});

var UserList = Backbone.Collection.extend({
  model : User
});

Very same extend()

Example benefit

create()

var users = new UserList();

users.create({ name : 'Jack' });

Behind the scenes

Passed raw data to Collection::create() Collection passed that to our model Our model was created with the passed data Automatically synced with the server Our model was added to our collection

In one line

Collections

Just simple conventions around simple ideas.

Organizing your data so you don't have to.

Backbone Views

Very Lightweight UI components

Mostly convention and convenience, allowing you to move more quickly

Creating a View

Backbone.View.extend(properties [, classProperties]);

Still the same extend()

Special Properties

  • idAn element id
  • className Element classes
  • tagName The tag to use
  • attributes Element attributes
  • el An actual element
  • events Events to listen to

View.render()

The heart of any view is its render() method which, by default, does nothing

Yes, nothing.

The sugar

this.el; // The dom element you have
this.$el; // a cached jQuery instance of your el
this.$(); // a jQuery method scoped to your el

View Events

var MyView = Backbone.View.extend({
  events : {
    'click .btn' : 'onButtonClick'
  },
  onButtonClick : function(evt) {
    // automatically called
  }
});

Wiring it all together

Listening and acting on events

var MyView = Backbone.View.extend({
  initialize : function() {
    this.collection.on('all', this.render, this);
  },
  render : function() {
    // Do some rendering magic
  }
});

Voila, a cheap re-render when your collection changes.

Backbone is not magic

You don't do everything "in backbone"

It is just another tool

There is a cost

You will need to find new solutions and how to recognize new patterns

But you need something.

Backbone's a good start