Professional Documents
Culture Documents
Agenda
Why do you need to learn how to program HTML5 web apps? A walkthrough over the To-Do list anatomy
https://github.com/ronreiter/webapp-boilerplate
Why?
Web Apps = Software as a Service
Cross OS/platform/browser Cuts costs on deployment and maintenance Scales easily
Mobile Apps
Cross device development cuts development costs WebView PhoneGap
Brief Introduction
Google App Engine - Solid, scalable server framework
Platform as a Service
REST API
Back-End
Dataset
We want to create a Todo list item table. Start by adding a Google App Engine model
done = db.BooleanProperty()
order = db.IntegerProperty()
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)
def get(self):
self.response.out.write( template.render("index.html", {}))
Similar to SQL, but this is a customized interface and not a way to access a database REST API uses XML or JSON serialization (Javascript Object Notation) to encode and decode objects Well use JSON
for todo in Todo.all(): todos.append({ "id" : todo.key().id(), "content" : todo.content, "done" : todo.done,
"order" : todo.order,
})
todo = Todo( content = data["content"], done = data["done"], order = data["order"], ).put() # create the todo item
self.response.out.write(simplejson.dumps({
"id" : todo.id(), "content" : data["content"], "done" : data["done"], "order" : data["order"], }))
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
self.response.out.write(simplejson.dumps({
"id" : id, "content" : todo.content, "done" : todo.done, "order" : todo.order, }))
# find the requested model and delete it. todo = Todo.get_by_id(int(id)) todo.delete()
Front-End
Backbone.Model
Model
HTML + CSS
DOM Manipulation With jQuery and templating
View
Model Events
Backbone.View
Controller
View Events
Collection
View View View View Model Model Model Model
Model Operations PUT /tasks/38 DELETE /tasks/38 PUT /tasks/39 DELETE /tasks/39 PUT /tasks/40 DELETE /tasks/40 PUT /tasks/41 DELETE /tasks/41
index.html
Loads the stylesheet <link rel="stylesheet" href="css/todos.css/> Loads the main.js script <script data-main="js/main" src="js/libs/require/require.js"> </script>
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' } });
main.js cont.
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 new way to write Javascript modules.
Since there is only one app, well use an existing element for the AppView. However, task views are more dynamic, and they will create new DOM elements.
Todos.bind('reset', this.addAll);
Todos.fetch(); },
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'); }); } });
});
return TodoModel; });
this.model.bind('change', this.render);
this.model.bind('destroy', this.remove); }, render: function() { $(this.el).html(this.template(this.model.toJSON()));
...
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
<div class="todo <%= done ? 'done' : '' %>"> <div class="display"> <input class="check" type="checkbox" <%= done ? 'checked="checked"' : '' %> /> <div class="todo-content"><%- content %></div> <span class="todo-destroy"></span> </div> <div class="edit"> <input class="todo-input" type="text" value="<%- content %>" /> </div> </div>
Questions?