Created
April 10, 2012 19:08
-
-
Save rubenfonseca/2353736 to your computer and use it in GitHub Desktop.
Backbone + Titanium - part 2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Customise Backbone.sync to work with Titanium rather than jQuery | |
var getUrl = function(object) { | |
if (!(object && object.url)) return null; | |
return _.isFunction(object.url) ? object.url() : object.url; | |
}; | |
Backbone.sync = (function() { | |
var methodMap = { | |
'create': 'POST', | |
'read' : 'GET', | |
'update': 'PUT', | |
'delete': 'DELETE' | |
}; | |
return function(method, model, options) { | |
var xhr = Ti.Network.createHTTPClient({ timeout: 35000 }); | |
var type = methodMap[method], | |
params = _.extend({}, options); | |
//==== Start standard Backbone.sync code ==== | |
// Ensure that we have a URL | |
if (!params.url) params.url = getUrl(model) || urlError(); | |
// Ensure that we have the appropriate request data. | |
if (!params.data && model && (method == 'create' || method == 'update')) { | |
params.data = model.toParams(); | |
} | |
// For older servers, emulate JSON by encoding the request into an HTML-form. | |
if (Backbone.emulateJSON) { | |
params.contentType = 'application/x-www-form-urlencoded'; | |
params.processData = true; | |
params.data = params.data ? {model : params.data} : {}; | |
} | |
// For older servers, emulate HTTP by mimicking the HTTP method with `_method` | |
// And an `X-HTTP-Method-Override` header. | |
if (Backbone.emulateHTTP) { | |
if (type === 'PUT' || type === 'DELETE') { | |
if (Backbone.emulateJSON) params.data._method = type; | |
params.type = 'POST'; | |
params.beforeSend = function(xhr) { | |
xhr.setRequestHeader('X-HTTP-Method-Override', type); | |
}; | |
} | |
} | |
//==== End standard Backbone.sync code ==== | |
//Handle success | |
xhr.onload = function() { | |
var cookies = this.getResponseHeader('Set-Cookie'); | |
if(cookies != null && Ti.Android) | |
Ti.App.Properties.setString('cookies', cookies); | |
params.success(JSON.parse(this.responseText)); | |
}; | |
//Handle error | |
xhr.onerror = params.error; | |
//Prepare the request | |
xhr.open(type, params.url); | |
//Add request headers etc. | |
if(params.contentType) | |
xhr.setRequestHeader('Content-Type', params.contentType); | |
xhr.setRequestHeader('Accept', 'application/json'); | |
if (params.beforeSend) params.beforeSend(xhr); | |
if(Ti.Android && Ti.App.Properties.getString('cookies')) | |
xhr.setRequestHeader('Cookie', Ti.App.Properties.getString('cookies')); | |
//Make the request | |
xhr.send(params.data); | |
}; | |
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Post extends Backbone.Model | |
urlRoot: app.endpoint + "/posts" | |
toParams: -> | |
# assuming you've stored an instance of the previous QueryStringBuilder class... | |
app.query_string_builder.stringify(this.attributes, "post") | |
class Posts extends Backbone.Collection | |
url: app.endpoint + "/posts" | |
model: Post | |
app.models.Post = Post | |
app.models.Posts = Posts |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class PostViewController | |
initialize: (@post) -> | |
# create @window and @tableView | |
data = [] | |
data.push @createTitleRow() | |
data.push @createBodyRow() | |
data.push @createAuthorRow() | |
@tableView.data = data | |
createTitleRow: -> | |
row = Ti.UI.createTableViewRow | |
title: @post.get('title') | |
@post.bind 'change:title', (e) => | |
row.title = @post.get('title') | |
row | |
# ... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class PostsViewController | |
# assumming an existing @tableView and @window | |
reload: -> | |
@posts = new app.models.Posts() | |
@posts.fetch | |
success: => | |
@prepareData(@posts.models) | |
error: (e) => | |
Ti.API.error JSON.stringify(e) | |
prepareData: (models) -> | |
@tableView.data = _.map models, (model) -> | |
{ title: model.get('title'), model: model, hasChild: true } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class QueryStringBuilder | |
stringify: (obj, prefix, accum = {}) -> | |
if _.isArray(obj) | |
this.stringifyArray obj, prefix, accum | |
else if _.isString(obj) || _.isNumber(obj) || _.isDate(obj) || "#{obj}" == "[object TiBlob]" | |
this.stringifyString obj, prefix, accum | |
else if _.isBoolean(obj) | |
this.stringifyBoolean obj, prefix, accum | |
else if obj? | |
if obj.attributes? | |
this.stringifyObject obj.attributes, prefix, accum | |
else | |
this.stringifyObject obj, prefix, accum | |
else | |
return prefix | |
accum | |
stringifyBoolean: (bool, prefix, accum) -> | |
unless prefix | |
throw new TypeError("Stringify expects an object") | |
accum[prefix] = if bool then 1 else 0 | |
stringifyString: (str, prefix, accum) -> | |
unless prefix | |
throw new TypeError("Stringify expects an object") | |
accum[prefix] = str | |
stringifyArray: (arr, prefix, accum) -> | |
unless prefix | |
throw new TypeError("Stringify expects an object") | |
i = 0 | |
for item in arr | |
this.stringify(item, "#{prefix}[#{i++}]", accum) | |
stringifyObject: (obj, prefix, accum) -> | |
for key, value of obj | |
continue if key.match(/_preview$/) | |
new_key = key | |
if _.isArray(value) | |
new_key = "#{key}_attributes" | |
new_prefix = '' | |
if prefix | |
new_prefix = "#{prefix}[#{encodeURIComponent(new_key)}]" | |
else | |
new_prefix = encodeURIComponent new_key | |
this.stringify value, new_prefix, accum |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment