writing html5 web apps (1)

Upload: bojja2011

Post on 06-Apr-2018

230 views

Category:

Documents


0 download

TRANSCRIPT

  • 8/3/2019 Writing HTML5 Web Apps (1)

    1/32

    Writing HTML5Web Apps

    Google App Engine

    Backbone.js

    Require.js

    jQuery

    Ron Reiter 2012

  • 8/3/2019 Writing HTML5 Web Apps (1)

    2/32

    Agenda

    Why do you need to learn how to program HTML5 webapps?

    A walkthrough over the To-Do list anatomy

    https://github.com/ronreiter/webapp-boilerplate

  • 8/3/2019 Writing HTML5 Web Apps (1)

    3/32

    Why?

    Web Apps = Software as a Service

    Cross OS/platform/browser

    Cuts costs on deployment and maintenance

    Scales easily

    Google App Engine, Amazon, Heroku, etc.

    Mobile Apps

    Cross device development cuts development costs

    WebView

    PhoneGap

  • 8/3/2019 Writing HTML5 Web Apps (1)

    4/32

    Brief Introduction

    Google App Engine - Solid, scalable server framework

    Platform as a Service

    Backbone.js - Proven MVC framework

    LinkedIn mobile, Foursquare, Do.com, Groupon, Posterous,Basecamp mobile, Kicksend, etc...

    Require.js - Modular JavaScript Loader

    Module dependency management

    JavaScript minification & bundling

    jQuery - DOM Manipulation Framework

    Creating dynamic content and replacing Flash

  • 8/3/2019 Writing HTML5 Web Apps (1)

    5/32

    The To-Do List

  • 8/3/2019 Writing HTML5 Web Apps (1)

    6/32

    Web App Architecture

    Front End

    Backbone.js

    Back End

    Google App Engine

    REST API

  • 8/3/2019 Writing HTML5 Web Apps (1)

    7/32

    Back-End

  • 8/3/2019 Writing HTML5 Web Apps (1)

    8/32

    Dataset

    We want to create a Todo list item table.

    Start by adding a Google App Engine model

    # the Todo model.

    class Todo(db.Model):

    content = db.StringProperty()

    done = db.BooleanProperty()

    order = db.IntegerProperty()

  • 8/3/2019 Writing HTML5 Web Apps (1)

    9/32

    Request Handler

    Serves all web requests

    We implement a main handler and REST API

    def main():

    application = webapp.WSGIApplication([# index.html

    ('/', MainHandler),

    # REST interface

    ('/todos', TodoListHandler),

    ('/todos/(\d+)', TodoItemHandler),

    ], debug=True)

    util.run_wsgi_app(application)

  • 8/3/2019 Writing HTML5 Web Apps (1)

    10/32

    Main Request Handler

    When we access http://www.todolist.com, the app isdownloaded to our computer and starts to run.

    class MainHandler(webapp.RequestHandler):

    def get(self):

    self.response.out.write(

    template.render("index.html", {}))

    http://www.todolist.com/http://www.todolist.com/
  • 8/3/2019 Writing HTML5 Web Apps (1)

    11/32

    REST API Standard

    REST API is used to let clients control datasets, using fourCRUD operations:

    Create a new itemusing HTTP POST requests

    Read a list of itemsusing HTTP GET requests

    Update a single itemusing HTTP PUT requests

    Delete a single itemusing HTTP DELETE requests

    Similar to SQL, but this is a customized interface and not away to access a database

    REST API uses XML or JSON serialization (Javascript ObjectNotation) to encode and decode objects

    Well use JSON

  • 8/3/2019 Writing HTML5 Web Apps (1)

    12/32

    REST APIGET (get all tasks)

    class TodoListHandler (webapp.RequestHandler):

    def get(self):

    # serialize all Todos,

    # include the ID in the response

    todos = []

    for todo in Todo.all():

    todos.append({

    "id" : todo.key().id(),

    "content" : todo.content,

    "done" : todo.done,

    "order" : todo.order,

    })

    # send them to the client as JSON

    self.response.out.write(simplejson.dumps(todos))

  • 8/3/2019 Writing HTML5 Web Apps (1)

    13/32

    REST APIPOST (add a new task)

    class TodoListHandler (webapp.RequestHandler):

    def post(self):

    data = simplejson.loads(self.request.body) # load JSON data of the object

    todo = Todo(

    content = data["content"],done = data["done"],

    order = data["order"],

    ).put() # create the todo item

    # send it back, and include the new ID.

    self.response.out.write(simplejson.dumps({

    "id" : todo.id(),

    "content" : data["content"],

    "done" : data["done"],

    "order" : data["order"],

    }))

  • 8/3/2019 Writing HTML5 Web Apps (1)

    14/32

    REST APIPUT (update a task)

    class TodoItemHandler (webapp.RequestHandler):

    def put(self, id):

    data = simplejson.loads(self.request.body) # load the updated model

    todo = Todo.get_by_id(int(id)) # get it model using the ID from the request path

    todo.content = data["content"]todo.done = data["done"]

    todo.order = data["order"]

    todo.put() # update all fields and save to the DB

    # send it back using the updated values

    self.response.out.write(simplejson.dumps({

    "id" : id,

    "content" : todo.content,

    "done" : todo.done,

    "order" : todo.order,

    }))

  • 8/3/2019 Writing HTML5 Web Apps (1)

    15/32

    REST APIDELETE (delete a task)

    class TodoItemHandler (webapp.RequestHandler):

    def delete(self, id):

    # find the requested model and delete it.

    todo = Todo.get_by_id(int(id))

    todo.delete()

  • 8/3/2019 Writing HTML5 Web Apps (1)

    16/32

    Front-End

  • 8/3/2019 Writing HTML5 Web Apps (1)

    17/32

    Backbone.js ArchitectureMVC

    ViewHTML + CSS

    ControllerBackbone.View

    ModelBackbone.Model

    DOM ManipulationWith jQuery andtemplating

    View Events

    Backbone REST Sync

    Server Model Database

    Model Events

  • 8/3/2019 Writing HTML5 Web Apps (1)

    18/32

    Backbone.js ArchitectureREST Sync

    ModelView

    ModelView

    ModelView

    ModelView

    Collection

    PUT /tasks/41DELETE /tasks/41

    PUT /tasks/39DELETE /tasks/39

    PUT /tasks/40DELETE /tasks/40

    PUT /tasks/38DELETE /tasks/38

    GET /tasksPOST /tasks

    Collection OperationsModel Operations

  • 8/3/2019 Writing HTML5 Web Apps (1)

    19/32

    Web App Directory Structure

    index.htmlMain entry point

    css

    todos.cssDefines the style

    js

    libs

    require.js, jQuery, Backbone, Underscore models

    todo.jsThe todo item model

    collections

    todos.jsThe todo item collection

    views

    todos.jsThe todo item view

    App.jsThe app view

    templates

    stats.html

    todo.htmlThe todo item template

    main.js Require.js entry point

  • 8/3/2019 Writing HTML5 Web Apps (1)

    20/32

    index.html

    Loads the stylesheet

  • 8/3/2019 Writing HTML5 Web Apps (1)

    21/32

    main.js

    Configures paths and known libraries

    text is used for require.js text loading (for templates)

    require.config({paths: {

    jquery: 'libs/jquery/jquery-min',

    underscore: 'libs/underscore/underscore-min',

    backbone: 'libs/backbone/backbone-optamd3-min',

    text: 'libs/require/text'

    }

    });

  • 8/3/2019 Writing HTML5 Web Apps (1)

    22/32

    main.jscont.

    Load the app view (views/app.js)

    Notice there is no need to add the JS extension

    Require.js supplies us with a function to run Javascript

    code only after certain modules have been loaded.

    This allows us to create a dependency model, and a newway to write Javascript modules.

    require(['views/app'], function(AppView){

    var app_view = new AppView;

    });

  • 8/3/2019 Writing HTML5 Web Apps (1)

    23/32

    views/app.jsThe AppView

    Backbone's "View" is actually a "View Controller". The viewitself is the template combined with CSS.

    Creating a new view either means

    creating a new DOM element using JavaScript/jQuery ortemplating

    Using an existing one in the DOM

    Since there is only one app, well use an existing elementfor the AppView.

    However, task views are more dynamic, and they willcreate new DOM elements.

  • 8/3/2019 Writing HTML5 Web Apps (1)

    24/32

    views/app.jsThe AppView (cont.)

    The define function allows us to depend on libraries,template files and other modules we wrote.

    Every dependency in the list corresponds to an argumentof the function to execute once all modules are loaded.

    define([

    'jquery, 'underscore', 'backbone',

    'collections/todos, 'views/todos',

    'text!templates/stats.html'

    ], function($,_, Backbone,

    Todos, TodoView, statsTemplate) {

    var AppView = Backbone.View.extend({ ...

  • 8/3/2019 Writing HTML5 Web Apps (1)

    25/32

    views/app.jsThe AppView (cont.)

    The "View" captures and delegates events on DOMelements

    events: {"keypress#new-todo": "createOnEnter",

    "click.todo-clear a": "clearCompleted

    },

  • 8/3/2019 Writing HTML5 Web Apps (1)

    26/32

    views/app.jsThe AppView (cont.)

    We add some handlers on the Todos collection to getnotified when it's updated.

    Then, we fetch the Todos collection from the server.

    Once the data is loaded, addAll will be executed.

    initialize: function() {

    Todos.bind('add', this.addOne);

    Todos.bind('reset', this.addAll);

    Todos.fetch();

    },

  • 8/3/2019 Writing HTML5 Web Apps (1)

    27/32

    collections/todos.jsTodo Collection

    Backbone Collections are model arrays which synchronize with the server.

    The AppView listens for changes on this collection, and can add new models to it.

    define([

    'underscore', 'backbone', 'models/todo

    ], function(_, Backbone, Todo){

    var TodosCollection = Backbone.Collection.extend({

    model: Todo,

    url: '/todos',

    done: function() {

    return this.filter(function(todo){

    return todo.get('done');

    });

    }

    });

  • 8/3/2019 Writing HTML5 Web Apps (1)

    28/32

    models/todo.jsTodo Model

    Holds the Todo item data

    Defines the default values and methods related to the data

    The "define" function needs to return the model class. When"model/todo" will be required, it will be received.

    define(['underscore', 'backbone'], function(_, Backbone) {

    var TodoModel = Backbone.Model.extend({

    defaults: { content: "empty todo..., done: false, order: 0 }

    });

    return TodoModel;

    });

  • 8/3/2019 Writing HTML5 Web Apps (1)

    29/32

    views/todos.jsTodo View

    Bind the view to the model

    Render function uses the model data to render the template

    define(['jquery', 'underscore', 'backbone, 'models/todo',

    'text!templates/todos.html'], function($,_, Backbone, Todo, todosTemplate){

    var TodoView = Backbone.View.extend({

    model: Todo,

    template:_.template(todosTemplate),

    initialize: function() {

    this.model.bind('change', this.render);

    this.model.bind('destroy', this.remove);

    },

    render: function() {

    $(this.el).html(this.template(this.model.toJSON()));

    ...

  • 8/3/2019 Writing HTML5 Web Apps (1)

    30/32

    views/todos.jsTodo View

    (cont.) Manipulate the view's model according to triggered events

    events: {

    "click.check" : "toggleDone",

    ...

    }

    // Toggle the "done" state of the model.

    toggleDone: function() {

    this.model.save({done : !this.model.get("done")});

    },

  • 8/3/2019 Writing HTML5 Web Apps (1)

    31/32

    templates/todos.html

    Template files are used to build the views either:

    Once (and then update using jQuery)

    On every update (if you're lazy)

    Use for escaping HTML

  • 8/3/2019 Writing HTML5 Web Apps (1)

    32/32

    Questions?