2012年8月30日 星期四
2012年8月16日 星期四
HTML5 Application Cache
一.說明
HTML5提供了Application Cache機制,可以讓靜態檔案Cache在Client端
減少對Server的Request,加速頁面載入,當網站上資料有異動,需要客戶端
更新Cache資料,也可以很簡易的做到,進一步還可以達到離線閱讀的目的
二.原理
要使用了Application Cache,必須在網站上加上一個manifest檔案
manifest檔案內設定了要cache的檔案清單,當Client連線後會儲存保留
menifest檔案在Client端,每次連線一定會去比對Client端的manifest檔案與
Server端上的manifest檔案是否有異,若有異動,則會重新由Server讀取檔案儲存到Client的Cache,否則就會去直接讀取Client端的Cache顯示頁面資料
三.Web Server上需要的設定
在Web Server上需要對manifest的檔案類型做MIME Type設定
副檔名可以自訂
通常會是用.manifest 或 .appcache
例 在Apache Web Server設定加上
四.網頁上使用
五.manifest檔案設定內容
六.注意事項
HTML5提供了Application Cache機制,可以讓靜態檔案Cache在Client端
減少對Server的Request,加速頁面載入,當網站上資料有異動,需要客戶端
更新Cache資料,也可以很簡易的做到,進一步還可以達到離線閱讀的目的
二.原理
要使用了Application Cache,必須在網站上加上一個manifest檔案
manifest檔案內設定了要cache的檔案清單,當Client連線後會儲存保留
menifest檔案在Client端,每次連線一定會去比對Client端的manifest檔案與
Server端上的manifest檔案是否有異,若有異動,則會重新由Server讀取檔案儲存到Client的Cache,否則就會去直接讀取Client端的Cache顯示頁面資料
三.Web Server上需要的設定
在Web Server上需要對manifest的檔案類型做MIME Type設定
副檔名可以自訂
通常會是用.manifest 或 .appcache
例 在Apache Web Server設定加上
AddType text/cache-manifest .manifest
四.網頁上使用
<html manifest='cache.manifest'>
在所有會成為進入點的網頁,都需要加入設定指向manifest檔案五.manifest檔案設定內容
CACHE MANIFEST 必要的第一行
CACHE:
區塊設定要cache的檔案清單
NETWORK:
區塊設定一定要由網路讀取的清單
FALLBACK:
區塊設定當讀取失敗,要轉向使用哪個替代內容顯示
例CACHE MANIFEST
#ver 0.0.1
CACHE:
index.htm
/js/main.min.js
/css/app.css
/img/btn_img.png
NETWORK:
*
FALLBACK:
六.注意事項
- 更新
要做任何檔案異動,除了檔案本身更動外,一定要讓manifest有所變化,否則系統只會一直讀取到Cache的資料,通常可以在manifest內加入一個版號宣告,只要有更動,客戶端即會自動更新Cache - 不使用cache
Application Cache與Browser一般的Cache暫存並不相同,並無法透過Browse的F5來清除, 要讓網頁不使用cache,必須透過刪除manifest內CACHE清單來達到 - 刪除manifest檔案
直接刪除Server上的manifest檔案,也會讓Client不使用Cache - 不要使用舊有的防檔案cache機制
通常會在讀取如js檔案會加上一個版號來控制檔案cache
例
使用Application Cache請不要再使用這樣的手法,把Cache的管理都交給manifest處理即可<script scr="xx.js?ver=1.0"></script>
2012年8月6日 星期一
Sencha Touch 2 : 在View內使用html,tpl與itemTpl
在View裡除了使用內建的Compontent外,若需要產生html來當作View的內容
可能會在View的Config內用到以下幾個3種Tag
一.html
直接將html內容放到view內,若有需要被操作的物件是以html產生,建議以此方式放入可使用
1.String
例 字串array會自動使用join串接
例 array需以join('')串接,否則會被當成整個字串顯示
二.tpl
當為動態資料產生的內容,利用setData傳入資料與tpl產生view的html內容,通常會在一般的view內使用
一定要有執行setData(),tpl才會被render產生html
1.String
設定tpl的動作一定要在執行setData前完成,也就是說可以設定在config的tpl
或是在initial程序內執行設定(在setData前設定好)
例 在config內設定
4.Ext.XTemplate[]
例
在initial內執行
只有在List View可以使用,會將List View所關聯的store或以setData設定array data
每筆資料套用到itemTpl上,注意這裡接受的是XTemplate
1.String
例
例
例
例
四.使用注意事項
可能會在View的Config內用到以下幾個3種Tag
一.html
直接將html內容放到view內,若有需要被操作的物件是以html產生,建議以此方式放入可使用
1.String
例 字串array會自動使用join串接
html:[
"this html block..........",
"kkman"
].join('')
2.HTMLElement例 array需以join('')串接,否則會被當成整個字串顯示
html:[
"<div>this html block..........</div>",
"<hr/>",
"<div>hello</div>"
].join('')
3.Ext.Element ?? 二.tpl
當為動態資料產生的內容,利用setData傳入資料與tpl產生view的html內容,通常會在一般的view內使用
一定要有執行setData(),tpl才會被render產生html
1.String
tpl:"<div><div>Hello me</div><div>{name}</div><div>{rock}</div></div>"
tpl:[
"<div>",
"<div>Hello me</div>",
"<div>{name}</div>",
"<div>{rock}</div>",
"</div>"
].join('')
3.Ext.Template[]設定tpl的動作一定要在執行setData前完成,也就是說可以設定在config的tpl
或是在initial程序內執行設定(在setData前設定好)
例 在config內設定
tpl:new Ext.Template("<div>Hello {name}.</div>")
例 在initial程序中使用this.setTpl(new Ext.Template("<div>Hello me {name}.</div>"))
4.Ext.XTemplate[]
例
在initial內執行
this.setData([
{
name:'ozzy',
type:'metal'
},
{
name:'linda',
type:'Rock'
}
]);
在config內設定tpl:new Ext.XTemplate(
'<tpl for=".">',
'<p>{name}</p>',
'<p>{type}</p>',
'<hr>',
'</tpl>'
)
三.itemTpl只有在List View可以使用,會將List View所關聯的store或以setData設定array data
每筆資料套用到itemTpl上,注意這裡接受的是XTemplate
1.String
例
itemTpl:'<p> {name}</p><p> {type}</p>'
2.String[]例
itemTpl:[
'<p>{name}</p>',
'<p>{type}</p>',
'<hr>'
].join('')
3.Ext.XTemplate例
itemTpl:new Ext.XTemplate(
'<p>{name}</p>',
'<p>{type}</p>',
'<hr>'
)
4.使用setData 例
var list={
xtype:'list',
itemId:'mylist',
itemTpl:new Ext.XTemplate(
'<p>{name}</p>',
'<p>{type}</p>',
'<hr>'
)
}
this.getComponent('mylist').setData([
{
name:'ozzy',
type:'metal'
},
{
name:'linda',
type:'Rock'
}
]);
四.使用注意事項
- 不要同時將html與tpl並用,否則html部份資料不會顯示
- 使用html,內容會被包覆在多層次的innerHtml class node內使用tpl則是將內容直接append進去不做任何節點包裝
- 若設定的資料為array資料,在tpl內使用for來處理迴圈,list一定要用itemTpl不可使用tpl
2012年7月18日 星期三
Sencha Touch 2 : Model
一.Model功能
1.定義資料架構
model被用來定義在應用程式中所要使用的資料架構,也就是說定義好model內的資料欄位(field)將取得的資料包裝成model物件後,就可以用model所提供的方法來操作
2.與Store配合使用
model大多與store一起使用,當store使用proxy載入資料後,會將資料轉成model物件,model本身也可以定義proxy,自行載入資料,但比較不建議這樣使用,因Store可以透過Ext.getStore()讓store可以在各個地方使用,model則沒辦法,主要還是把model當作資料架構定義與資料內容驗證用
3.Ext.data.Model包含了四個部分
當由server取到json物件要儲存到model欄位
若要儲存到欄位的資料為物件,type可設定為auto
在tmpl內要取用欄位資料用{xxx.xxx}方式往下讀取即可
例
三.驗證Validations
對指定的欄位設定驗證規則
在validastions內可設定多條規則
每筆包含type:驗證項目,field:要驗證的欄位
type可使用的值為
四.關聯Associations
設定好關聯性可以讓model內可包含其他的model
可以在取得資料後,把資料塞到各階層的model內
如果不使用關聯性設定,欄位的內容只是一個object
使用關聯性設定可以讓欄位內容是一個model
1.設定關聯性範例
2.使用關聯性範例
例
五.id屬性
若model內的data值有id,這id值也會被copy到model上產生internalId值
當model.getId()會取到這internalId值
若有用idProperty指定哪個欄位當id值,則該欄位會被copy到internalId
若資料內沒id值,也沒設定idProperty,就會用系統自己產生的id值
例
否則無法儲存到localStorage上
六.載入資料
model要執行load必須透過Class執行,且執行結果必須要是array,若不是,同樣需要在rootProperty內先處理
七.使用資料
1.定義資料架構
model被用來定義在應用程式中所要使用的資料架構,也就是說定義好model內的資料欄位(field)將取得的資料包裝成model物件後,就可以用model所提供的方法來操作
2.與Store配合使用
model大多與store一起使用,當store使用proxy載入資料後,會將資料轉成model物件,model本身也可以定義proxy,自行載入資料,但比較不建議這樣使用,因Store可以透過Ext.getStore()讓store可以在各個地方使用,model則沒辦法,主要還是把model當作資料架構定義與資料內容驗證用
3.Ext.data.Model包含了四個部分
- Fields:欄位定義
- Proxies:設定取資料用proxy
- Associations:設定model間關聯性
- Validations:驗證
當由server取到json物件要儲存到model欄位
若要儲存到欄位的資料為物件,type可設定為auto
在tmpl內要取用欄位資料用{xxx.xxx}方式往下讀取即可
例
Ext.define('User', {
extend: 'Ext.data.Model',
config: {
fields: [
{name: 'id', type: 'int'},
{name: 'name', type: 'string'},
{name: 'obj', type: 'auto'},
]
}
});
三.驗證Validations
對指定的欄位設定驗證規則
在validastions內可設定多條規則
每筆包含type:驗證項目,field:要驗證的欄位
type可使用的值為
- presence:檢查是否有值,0是有效的,空值則無效
- length:可設定最長(max),或最少(min)字元
- format:檢查字串形式,用reg express檢查
- inclusion:設定允許使用的字串
- exclusion:設定不允許使用的字串
Ext.define('User', {
extend: 'Ext.data.Model',
config: {
fields: [
{name: 'id', type: 'int'},
{name: 'name', type: 'string'},
{name: 'obj', type: 'auto'},
],
validations: [
{ type: 'presence', field: 'id' },
{ type: 'presence', field: 'name', message: '不可空白'}
]
}
});
四.關聯Associations
設定好關聯性可以讓model內可包含其他的model
可以在取得資料後,把資料塞到各階層的model內
如果不使用關聯性設定,欄位的內容只是一個object
使用關聯性設定可以讓欄位內容是一個model
1.設定關聯性範例
Ext.define('User', {
extend: 'Ext.data.Model',
config: {
fields: [
{name: 'id', type: 'int'},
{name: 'name', type: 'string'}
],
hasMany: {model: 'Product', name: 'products'}
}
});
代表User內有一個products屬性,這個屬性內儲存著Product Model的Array2.使用關聯性範例
User.load(1, {
success: function(user) {
console.log("User: " + user.get('name'));
user.posts().each(function(post) {
console.log(post.get('title'));//post本身即是一個model
post.comments().each(function(comment) {//post內的comment也是一個model
console.log(comment.get('message'));
});
});
}
});
3.當model有設定belongTo,就可以取得其上層model instance例
Ext.define('User', {
extend: 'Ext.data.Model',
config: {
fields: [
{name: 'id', type: 'int'},
{name: 'name', type: 'string'}
],
hasMany: {model: 'Post', name: 'prosts'}
}
});
Ext.define('Post', {
extend: 'Ext.data.Model',
config: {
fields: [
{name: 'id', type: 'int'},
{name: 'name', type: 'string'}
],
belongsTo: 'User'
}
});
post.getUser(function(user) {//非同步,要透過callback取得user
console.log('post: ' + user.get('name'))
});
五.id屬性
若model內的data值有id,這id值也會被copy到model上產生internalId值
當model.getId()會取到這internalId值
若有用idProperty指定哪個欄位當id值,則該欄位會被copy到internalId
若資料內沒id值,也沒設定idProperty,就會用系統自己產生的id值
例
Ext.define("Stest.model.ItemModel", {
extend: "Ext.data.Model",
config: {
idProperty: 'firstName',
fields: [
{ name: 'firstName', type: 'string' },
{ name: 'lastName', type: 'string'}
]
}
});
注意:當作localStorage Store使用的model,不可使用id field,必須由系統產生否則無法儲存到localStorage上
六.載入資料
model要執行load必須透過Class執行,且執行結果必須要是array,若不是,同樣需要在rootProperty內先處理
Ext.define("Stest.model.ItemModel", {
extend: "Ext.data.Model",
config: {
idProperty: 'firstName',
fields: [
{ name: 'firstName', type: 'string' },
{ name: 'lastName', type: 'string'}
]
}
});
七.使用資料
- model.raw : 取到原始資物物件
- model.getData() : 取到修改過的資料物件
- model.get('欄位名稱') : 取到指定欄位值
Sencha Touch 2 : Store 載入資料的後處理
一.需要處理的狀況
當Store取得資料,目標是將資料轉成model Array以方便使用Store提供的功能如find,sorter filter等操作,可能遇到狀況
在載入資料時,rootProperty會先執行,然後才是執行load的listener
load listener內的資料已經是經過rootProperty處理過的資料
二.rootProperty
rootProperty是用在當由Server取得JSON物件資料,用來告訴Store在載入資料後,
由哪個節點開始解析放入model,通常會是節點名稱的字串值,也可以是一個function,
如果取得Server端的JSON已經是個Array,則rootProperty的設定是無效不會被執行到的
例
以下Store會以資料的users內容產生models
資料來源
Store
三.Load Event Listener
四.回傳值為Array的處理範例
rootProperty不需設定,只要在listener load內處理所要的變化
例
五.回傳為物件的處理方式
rootProperty設定回傳array部份,其他值的變化由load event listener處理
例
六.處理過後的資料使用
例
當Store取得資料,目標是將資料轉成model Array以方便使用Store提供的功能如find,sorter filter等操作,可能遇到狀況
- 取得的資料為物件,只取物件中array的部份產生model array
- 載入的資料欄位需要先作一些修改處理,才能存到model內
在載入資料時,rootProperty會先執行,然後才是執行load的listener
load listener內的資料已經是經過rootProperty處理過的資料
二.rootProperty
rootProperty是用在當由Server取得JSON物件資料,用來告訴Store在載入資料後,
由哪個節點開始解析放入model,通常會是節點名稱的字串值,也可以是一個function,
如果取得Server端的JSON已經是個Array,則rootProperty的設定是無效不會被執行到的
例
以下Store會以資料的users內容產生models
資料來源
{
meta:{},
users:[
{},{}...
]
}
Store
Ext.define("My.store.MyStore", {
extend: "Ext.data.Store",
config: {
model: "My.model.UserModel",
proxy: {
type: 'ajax',
reader: {
type: 'json'
}
},
rootProperty:"users"
}
});
三.Load Event Listener
- 在資料載入後,load event會被觸發
通常對要存入model的欄位值要做改變,可以在load event內做,也可以在rootProperty內處理,但最好統一在load event內做,因為如果資料來源是array,rootProperty並不會被執行到,可能會造成錯誤 - load evnet內會接收到records 與store參數,要對資料做處理可以使用records這或store來操作都可
- load event被觸發時,取得的records是該次fetch取得的資料,而非總資料量
四.回傳值為Array的處理範例
rootProperty不需設定,只要在listener load內處理所要的變化
例
Ext.define("My.store.MyStore", {
extend: "Ext.data.Store",
config: {
model: "My.model.UserModel",
proxy: {
type: 'ajax',
reader: {
type: 'json'
}
}
}
listeners:{
load:function(store,records,_success,operation,opts){
for(var i=0;i
records[i].set('uid',records[i].get('id'));
delete records[i].getData().id;
}
}
}
});
五.回傳為物件的處理方式
rootProperty設定回傳array部份,其他值的變化由load event listener處理
例
Ext.define("My.store.MyStore", {
extend: "Ext.data.Store",
config: {
model: "My.model.MyModel",
proxy: {
type: 'ajax',
reader: {
type: 'json',
rootProperty:function(data){
return data.users
}
}
},
listeners:{
load:function(store,records,_success,operation,opts){
for(var i=0;i
records[i].set('uid',records[i].get('id'));
delete records[i].getData().id;
}
//---兩種方式都可以----
store.each(function(record, index){
record.set('index', index);
},store)
}
}
}
});
六.處理過後的資料使用
- Store如果被加工過,那取資料要由model.getData()取,不要由model.raw取
- 要將資料放到其他store內,不要直接將records(models array加進去) 而是由所有model取出資料,放data array而非models array比較安全
例
listeners:{
load:function(store,records,_success,operation,opts){
var _objs=[];
for(var i=0;i
records[i].set('uid',records[i].get('id'));
delete records[i].getData().id;
_objs.push(records[i].getData())
}
var anotherStore=Ext.getStore('AnotherStore');
localStore.add(_objs);
}
}
訂閱:
文章 (Atom)