4. Basically...
Get a WebKit-based desktop browser
Get some emulators & real devices
Download the Sencha Touch 2 PR2 SDK
Develop against a local web server
Optional, but highly recommended!
29. Child component patterns I
var
list
=
new
Ext.List({
store:
store,
...
});
instantiate component
var
panel
=
new
Ext.Panel({
items:
[list,
...],
...
});
reference component by var
30. Child component patterns II
preferable in ST2
var
list
=
Ext.create('Ext.List',
{
store:
store,
...
});
var
panel
=
Ext.create('Ext.Panel',
{
items:
[list,
...]
...
});
31. Child component patterns III
var
panel
=
Ext.create('Ext.Panel',
{
items:
[
{
xtype:
'list',
store:
store,
...
},
... deferred creation*
],
...
});
* a lightweight object until then
33. The list card
{
//
the
list
card
id:
'listCard', list should fill whole card
layout:
'fit',
items:
[{
//
main
top
toolbar
docked top toolbar
xtype:
'toolbar',
docked:
'top',
title:
'Please
wait'
//
will
get
added
once
city
known
},
{
//
the
list
itself
list*
//
gets
bound
to
the
store
once
city
known
id:
'dataList',
xtype:
'list'
}]
}
* list will be bound to a store later
34. The detail card
{
//
the
details
card
id:
'detailCard',
items:
[{
//
detail
page
also
has
a
toolbar
docked
:
'top',
xtype:
'toolbar',
title:
'' another docked toolbar*
},
{
//
textual
detail
}]
}
detail page to come later...
* title will be dynamically set
37. The YELP API...
http://api.yelp.com/business_review_search
?ywsid=YELP_KEY
&term=BUSINESS_TYPE free, rate limited
&location=CITY
business type, and city name
41. Create a data model
give the ‘class’ a name
Ext.define("Business",
{
extend:
"Ext.data.Model",
fields:
[
extending base model
{name:
"id",
type:
"int"},
{name:
"name",
type:
"string"},
{name:
"latitude",
type:
"string"},
{name:
"longitude",
type:
"string"},
{name:
"address1",
type:
"string"},
{name:
"address2",
type:
"string"},
{name:
"address3",
type:
"string"},
{name:
"phone",
type:
"string"},
{name:
"state_code",
type:
"string"},
{name:
"mobile_url",
type:
"string"},
{name:
"rating_img_url_small",
type:
"string"},
{name:
"photo_url",
type:
"string"},
]
});
and with these named, typed fields
42. <aside>
Models can be associated
with other models
Fields can also have default values,
conversion functions, and validation
</aside>
43. Create a model store
create the store
var
store
=
Ext.create('Ext.data.Store',
{
model:
"Business",
...
});
containing this
type of model
Think of a store as a ‘table’ of model instance ‘rows’
44. Configure data source
loads as soon as possible
var
store
=
Ext.create('Ext.data.Store',
{
model:
'Business',
autoLoad:
true,
proxy:
{ JSONP
//
call
Yelp
to
get
business
data
type:
'scripttag',
source
url:
'http://api.yelp.com/business_review_search'
+
'?ywsid='
+
YELP_KEY
+
'&term='
+
escape(BUSINESS_TYPE)
+
'&location='
+
escape(DEFAULT_CITY)
,
reader:
{
type:
'json',
root:
'businesses' construct API URL
}
}
});
read array from inside JSON
46. We can make the proxy URL dynamic,
which would allow geolocation.
But this requires an async
callback sequence.
47. Two-phase async sequence
getCity:
function
(callback)
{
callback(DEFAULT_CITY);
call when
//
this
could
now
be
a
geo
lookup
to
//
get
the
nearest
city
UI ready }, use this in the URL
getBusinesses:
function
(city,
callback)
{
Ext.define("Business",
{
...
});
the data code
we just wrote
var
store
=
Ext.create('Ext.data.Store',
{
...
});
} and this will need to fire the callback
with store when it autoloads
48. event
var
store
=
Ext.create('Ext.data.Store',
{ listeners
...
listeners:
{
//
when
the
records
load,
fire
the
callback
load:
function
(store)
{
callback(store);
when loaded
}
}
});
fire the callback with store
51. our 2 async functions
//
get
the
city
CB.getCity(function
(city)
{
//
then
use
Yelp
to
get
the
businesses
CB.getBusinesses(city,
function
(store)
{
//
then
bind
data
to
list
and
show
it
CB.cards.query('#dataList')[0].setStore(store);
});
});
get dataList bind the store to it
by its id
54. List items are templated
{
id:
'dataList',
xtype:
'list',
store:
null,
itemTpl:
'{name}'
}
model fields in curly braces
55. Spinner bound to store
instantiate mask over body
Ext.create('Ext.LoadMask',
Ext.getBody(),
{
store:
store,
msg:
''
});
will show when store is loading
56.
57. A more interesting template
itemTpl:
'<img
class="photo"
src="{photo_url}"
width="40"
height="40"/>'
+
'{name}<br/>'
+
'<img
src="{rating_img_url_small}"/> '
+
'<small>{address1}</small>'
HTML allowed
62. { when list items
selection
id:
'dataList',
...
are selected
listeners:
{
selectionchange:
function
(selectionModel,
records)
{
//
if
selection
made,
slide
to
detail
card
if
(records[0])
{
CB.cards.setActiveItem(1);
also fires on detail card
deselection
CB.cards.getActiveItem().setData(
records[0].data
);
...to detail
}
} apply record data... page template
}
}
63. A back button
items:
[{ children of toolbars
//
detail
page
also
has
a
toolbar are implicitly
docked
:
'top',
xtype:
'toolbar', xtype: ‘button’
title:
'',
items:
[{
//
containing
a
back
button
arrow style
//
that
slides
back
to
list
card
text:
'Back',
ui:
'back', back to list
listeners:
{
tap:
function
()
{
CB.cards.setActiveItem(0);
when tapped
}
}
}],
...
68. Remember this?
setData does not cascade into child items!
CB.cards.getActiveItem().setData(
records[0].data
);
69. Override setData
set title on toolbar
setData:
function
(data)
{
this.query('toolbar')[0].setTitle(data.name);
this.query('[cls="detail"]')[0].setData(data);
},
apply data to template on inner panel
83. O ine data
Taking Yelp data o ine
Taking images o ine
- src.sencha.io to generate cross-origin B64
Detecting network connection changes
http://sencha.com/x/df