Download - Writing HTML5 Web Apps (1)
-
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?