2012年2月22日 星期三

Backbone.js Model 06︰Sample

1.目標:
希望view監聽model的id變化,當id改變時,model抓取新的資料
依照資料做view外觀的改變

2.原作法:
監聽model上id變化,view跟著改變
model.set('id',xxx)
model.fetch()
model.on('change:id',this.doSomething)

3.問題:
當model id改變時,view馬上就收到通知
但此時,資料不見得已經fetch完成,可能出錯

4.解法:
在model內部監聽自己id變化,當id改變時
在model內加入isLoading的屬性=true
在fetch結束後,改變isLoading的屬性=false
view不再監聽model的id,改為監聽model的
isLoading
window.MyModel=Backbone.Model.extend({
    url:'js/data.json',
    initialize:function(){
        _.bindAll(this,'itemChange');
        this.on('change:id',this.itemChange);        
    },
    itemChange:function(){
        var that=this;
        this.set('isLoading',true);            
        this.fetch({
            success:function(response,model){                
                that.set('isLoading',false);
            }
        })
    }        
})
window.MyView=Backbone.View.extend({    
    initialize:function(){
        _.bindAll(this,'statusChange');
        this.model.on('change:isLoading',this.statusChange);
    },
    statusChange:function(){
        console.log('loading status='+this.model.get('isLoading'))    ;
    }    
})
window.model=new MyModel();
window.view=new MyView({
    model:window.model
})
model.set('id',1);

2012年2月21日 星期二

晚安 妹妹

下班回到家 妹妹已經在房間睡
吃完飯整理好
坐在電腦前 準備要開始晚上的工作

似乎聽到妹妹醒來的聲音
跑到床邊
妹妹看到了爸爸
微笑的張開雙手 抱住爸爸的臉
然後繼續睡著
晚安 妹妹

2012年2月19日 星期日

逸馨園 南雅夜市


昨天跟熙光到板橋的逸馨園 很不錯
想帶妹妹去玩 也帶老婆出去走走

天氣還是一樣很冷 騎著車還要再加件外套
茶坊在南雅夜市旁
選了個在兒童遊戲區旁的位置
就看妹妹興奮的跑來跑去

一會老婆覺得 無聊了
到外面夜市繞繞
回來 也是滿手的戰利品

離開茶坊
夜市的熱鬧 更是吸引人
妹妹一下撈魚 一下吃東西
回到家時 我們是滿手的食物
雖然沒有工作效率
不過 可以一家人一起
也是蠻好的


2012年2月16日 星期四

找到 台東老朋友


有時會想起在台東的日子
在地圖上找著過去營區的照片
看看是不是還跟記憶中的樣子一樣

當兵時的朋友
已經失聯了好久
也會想看他們現在好不好

突發奇想的在Google上輸入士官長的名字
找到了他女兒的部落格
找到了一篇他的專訪
退伍後的他
回到山上 做著原住民文化保存與傳承的工作
很佩服他

http://www.phototoyu.com/pics_info.jsp?photo_id=0902201415071320&mem_r_id=0812151827507568&link_mode=2&album_id=0902201414099692#go_here

試著在網站上留下資料
意外的在隔天得到了回應
打電話過去
電話那頭的聲音
還是一樣熟悉
找個時間 還要再回到台東
去看看他們


檢視較大的地圖

以前的營區已經是荒草一片
前面的釋迦攤應該還有在營業吧

2012年2月12日 星期日

Backbone.js Model 05︰Save

一.說明
使用model.fetch()會自Server讀取資料存到model上,使用model.save()則會是新增或更新資料到Server上,當在整個App操作時,model上的attributes資料有新增或更改時,呼叫model.save就會將資料上傳到server上,當model內沒有id值,系統會把save當作一個create的動作,新增一筆資料到Server,若是model內帶有id值,系統會當作是既有資料的更新update
二.Backbone.sync
Backbone.sync這個function在BackboneJS裡是真正執行與Server溝通的部份,但通常我們並不需要自己去定義sync function,也不需要自己去呼叫執行syn

當執行model.save()或是model.destroy()時會自動觸發執行Backbone.sync,而Backbone本身已經定義好sync function,預設是與RESTful的方式與Server做資料的傳送與接收,如果你要實做的新增刪除與修改的功能非RESTful,才需要自己改寫sync function
Backbone.sync=function(method,model,options){}
在sync被觸發時,sync會接收到3個參數
1.method:
當是在執行save method的值,會判斷如果model內無id值會當作是新增資料’create’,
若是有id值則method=’update’,當作是更新資料(或透過model.isNew判斷)
若是執行destroy則method=’delete’

2.model:
這代表執行save()的那個model物件(而非只是save時設定的改變值properties)
注意:這裡model是屬於model物件,必需要用model.get(‘prop’)來取值,若用model.prop就會出錯,model本身會帶有url,sync就會依更model內的url自動與server做溝通
3.options
接收到由model.save或model.destroy傳來的options設定,
[options]可以是success或error callback,這兩個callback同樣會接收到(model, response)參數

Backbone.sync=function(method,model,success,error){
    alert("method="+method+" model="+model.get("isLogin"));
};

三.model.save()
當執行save()後,Backbone.sync內接收到的model,會是整個model值都過去,即使用model.save([attributes]),Backbone.sync內接收到的model,還是整個model值都過去,而非只是save內所傳送的那幾項properties

model.save({isLogin:false})

四.model.save([attributes], [options]) 
1.[attributes]
先修改model內的attributies值,再進行save動作,
[attributes]是要改變的key-value
這樣的指令也就是同時包含以下兩個動作
model.set(attributes)
model.save()
2.[options] 要傳遞給sync用的選項
[options]可以是success或error callback,這兩個callback同要會接收到(model, response)
參數
例:
model.save(
    {isLogin:false},
    {error:function(model, response){..},
    {success:function(model, response){}
})

五.設定fetch與save使用不同url網址
model裡只有設定一個url值,fetch與save都會是使用同一個url去做處理,如果是使用REST,是可以用一個url就可以對應到CRUD的動作,但若非使用REST時,要讓不同的動作對應到不同的server端url處裡,可以有兩種方法
1.在執行fetch與save前,先傳入url網址再執行save與fetch

item.set({url:"save.php"})
item.save()    
2.改寫model內sync的function
先在model的sync內依照判斷把要傳遞的網址放到options內,再去改寫Backbone.sync,讓Backbone.sync依照接收到的options所帶的網址 做需要的處理

window.Item=Backbone.Model.extend({
    "sync":function(method, model, options){      
        switch(method){
        case "read":
            options.url = "json_sample/playerInfo.json";
            break;
        case "create":
            options.url = model.url + '/create';
            break;
        case "update":
            options.url = 'mytest/update.php';
            break;
        case "delete":
            options.url = model.url + '/delete';
            break;           
         }
    return Backbone.sync(method, model, options);
    }               
});

Backbone.sync=function(method,model,options){
    alert("from sync method="+method+" model="+JSON.stringify(model)+" url="+options.url);
};

注意:雖然fetch不會執行Backbone.sync,但還是可以在model.sync內得到url值
注意:當執行save要接收success event,如果不需要額外再帶參數,必須要在attribue的地方填上null
也就是model.save(null,{success:fun.....})

Backbone.js Model 04︰fetch

一.說明
model本身除了可以當作儲存資料的物件,透過Model本身提供的fetch與save method即可對Server做儲存與讀取,而要取得資料的server API路徑則是設定在model.url上

fetch與save都是透過jQuery或zepto的ajax來達成,所以在使用backboneJS之前一定要先導入jQuery(或zepto)與underscore

二.model.fetch()
當直接執行model.fetch()完成後,會由server端取得的json物件,所有的json物件屬性全部都會倒進model的atrribute內並觸發change event,這時如果有監聽attribute上的相關屬性,所設定的callback都會被觸發

server端 info.json

{
    "isLogin":true,
    "nowPlayList":"my",
    "nowPlayIndex":0 
}
client端
window.Item=Backbone.Model.extend()
window.item=new Item({id:5});
item.url="json_sample/Info.json";
item.fetch();
item.bind("change:isLogin",function(){
        console.log('chang isLogin')
})

當執行fetch()後會觸發change而跳出alert,且這時item這個model內已經有了來自server端的資料
alert(item.get(“isLogin”))//true

三.model.fetch({success,error})
如果fetch取得的結果需要做其他應用或要對fetch失敗做處裡,可以在fetch內設定success與error callback,所設定的success與error callback會接收到兩個參數response與jsonObj(jsonObj在api文件內是用model代表)

在success內接收到的兩個參數,jsonObj是取得資料的json物件,response則已經是個包了接收資料的model物件,也就是說response物件包了attributes屬性,並把server取得的資料都放到了attributes內


window.Item=Backbone.Model.extend({
    url:function(){
        return 'server/simple.json';
    },  
    myname:'OZClass'
});
window.item=new Item({});  
item.fetch({
    success:function(response,model){   
    }
})    

注意:
success內接收到的jsonObj是個json物件,所以可以用obj.prop方式(如jsonObj.nowPlayList)
來讀取json物件屬性,response則是一個model物件,則就需要靠response.get(“nowPlayList”)來取得),若這時候在success用jsonObj.get(“nowPlayList”)會出錯

四. parse
通常只需要使用Model內預設的parse method即可,在自訂Model class時並不需要再定義這method,平常在使用model時也不需要呼叫執行parse,當執行fetch取得資料後,model內部自動會把取得的結果先執行parse處裡過

如果有需要改變取得的內容再寫入model才需要寫parse method

在success中只能將response的結果做其他利用,如果希望改變response的結果,那就需要改寫
parse medthod
window.Item=Backbone.Model.extend({
    parse:function(response){
        response.name="["+response.name+"]";
        console.log(response.name)
        return response
    },
});



2012年2月9日 星期四

Backbone.js Model 03︰自訂Class與產生instance


一.自訂Model Class
自訂的Model Class一定要繼承自Backbone.Model,所產生的Model Class也可以再被繼承下去。
如果需要override一些Class屬性,則在宣告Class時傳進去。

var MyModelClass=Backbone.Model.extend(properties)
properties:想要overrde的Class屬性hash
例:
window.Item=Backbone.Model.extend({
    initialize:function(){
        this.set({url:"hi”})
    },
    defaults:{
        type:"rock"
    },
    my:"ozzy"
})
var item=new Item();
console.log(item.my) // “ozzy” Class Propery
console.log(item.get(“url”)) // “hi” attributes's property
console.log(item.get(“type”)) // “rock”

例:繼承自訂Model Class
window.MyItem=Item.extend({})

二.產生model instance
利用 new Model(prperties)產生instance
properties:所要傳入attributes內的屬性hash

instance可以改變attributes上的屬性值,也可自訂attributes上的prop,
可以改變model屬性值,但無法自訂model屬性值


window.MyModel=Backbone.Model.extend({
    initialize:function(){
        this.set("prop1",123)
    },
    my:'ozzy'
})
//--利用instance 設定與讀取class屬性
var model=new MyModel();
console.log(model.my)
model.my='sun';
console.log(model.my)
//--利用instance 設定與讀取class attributes的屬性
console.log(model.get('prop1'));
model.set("prop1",456);
console.log(model.get('prop1'));

三.自訂Class與產生instance時傳入的property
要設定initialize....等Class屬性一定要在宣告Class時設定進去
當然你也可以在設定initialize時,在initialize內設定attributes內的屬性內容

在產生model instance時,設定進去的則是attributes內的屬性值


2012年2月8日 星期三

Backbone.js Model 02︰Class基本屬性

所有的Model都必須繼承自Backbone.Model,在自訂Model Class時可以自訂屬於自己的Class屬性,不過在Backbone.Model上已經內建以下幾項屬性

1.id:
預設這項會是空的,當這個id值是空的時候,如果要把model資料save到Server上會當作是一筆新的資料處理(也就是create),若id值非空值,當執行save存到Server時會被當作是update。 通常在一開始對server取得資料(fetch)存到model上時,Server傳回的資料也會包含id值
當使用者若在attribute內設定了id,則這個id同時也會設定到model.id上,例如你設定了id,所以id不僅在model下有,在model.attributes下也會有一份

2.cid:
當model的instance產生時,每個model自動就會產生一個cid值,這樣即使在model沒有id的狀況下還是可以取得透過cid找到這個model


3.attributes:
跟Server取得的資料,也就是真正在程式內所要用到資料,都會儲存在attributes內。
model可以被監聽,指的是只有在attributes下的相關值發生變化,才可以被監聽,

model.on("change:prop",callback);
這prop是在model.attributes下,而非在model下


4.initialize:
如果有設定這項,這function會在產生Model的instance時被執行。在initialize內要設定attributes屬性值可利用this.set({xxx:xxx})來做,也已可取用model的其他屬性

initialize:function(){

    this.set({url:"hi”})

    console.log(this.cid)

},    

5.url:
model要跟server要資料(fetch)或是要存資料到server(save),都會透過這url設定的位置去執行,也就是說這就是設定Server API的位置。如果這個model是在Collection內,那麼url的值通常都會由collection提供不需自己設定。url除了可以設定字串,也可設定為一function回傳,可以function做運算後,依照狀況傳回當時所需的server端網址

window.ItemClass=Backbone.Model.extend({
  url:"json_sample/playerInfo.json"
})
window.item=new ItemClass({id:5});


window.Item=Backbone.Model.extend()
window.item=new Item({id:5});
item.url="json_sample/playerInfo.json";

url可以是透過function取得

window.Item=Backbone.Model.extend({
  url:function(){
    return "json_sample/playerInfo.json?id="+this.get("id");
  }
});

6.urlRoot:
當model並不在Collection內,也未設定url時,會以urlRoot/id來當作該model的 url

window.Item=Backbone.Model.extend()
window.item=new Item({id:5,isLogin:false});
item.urlRoot="json_sample/playerInfo.json";
item.fetch();
這設定會讓fetch會去查詢"json_sample/playerInfo.json/5 這個路徑
如果不要這種形式,那就需自行以url function方式取得你自訂的url路徑

7.defaults:
defaults內所設定的是attributes屬性的預設值
若model在產生instance時未設定的屬性都會以defaults內值為預設

8.sync:
當執行save或destroy,會透過model預設的sync來呼叫
Backbone.sync,通常是不需要改寫這部份
如果需要先經過另外處理再去執行Backbone.sync
則需要定義這一塊
例如,若要讓save與fetch使用不同的網址就會需要用到這部份

9.parse:
當執行fetch由server取到資料存到attributes內時,會自動執行parse動作,把接收到的內容response。通常我們不需自己去定義parse,使用Backbone內建的即可,但如果由server取到的資料,要用自己的格式存到attributes內,可以自訂parse改寫存入attributes的形式。 parse會接收到一個response參數,這參數就server端回傳的array或物件

window.MyItem=Backbone.Model.extend({
  url:"json_sample/playerInfo.json",
  parse:function(response){
    response.nowPlayList="["+response.nowPlayList+"]";           
    return response;
  }
})

window.item=new MyItem();
item.fetch();

例 只取用server回應的部份值
window.MyItem=Backbone.Model.extend({
  url:"json_sample/playerInfo.json",
  parse:function(response){
    return response.foo;
  }
})
window.item=new MyItem();
item.fetch();

10.model屬性存取與model.attributes下的屬性的存取
如果是讀取model下的屬性可以直接用
 model.prop來取得(如myModelInstance.id)
如果是讀取model.attributies下的屬性則需要
透過get取的(如myModelInstance.get(“myname”))

如果是要寫入model下的屬性可以直接用
 myModelInstance.myprop=xxx設定
如果是要寫入model.attributes下的屬性
則用myModelInstance.set(“myprop”,xxx)

11. unset用來移除model屬性
model.unset('id')
移除物件屬性為
delete obj.xxx   

2012年2月6日 星期一

Backbone.js Model 01︰用途與特性

1.當作一般資料儲存物件
當Client端要使用變數來暫存,可以把變數存在Model物件內,把Model當作一般物件般,做資料儲存

一般物件儲存
 var obj={  
      x:123,  
      y:456 
 }  
 console.log('obj x='+obj.x);  

Model物件儲存
 var model=new Backbone.Model({  
      x:123,  
      y:456  
 })   
 console.log('model x='+model.get('x'));  

2.可自行與Server溝通取得資料
Model本身內建fetch,save等method,只要設定好相關參數(url)Model即可自行與Server溝通取得資料,
也就是當由Server取得資料暫存在Client時,會將取得的資料以Model物件方式儲存在Client上

 var Item=Backbone.Model.extend({  
   url:function(){  
    return "json_sample/playerInfo.json?id="+this.get("id");  
   }  
 });  
 var item=new Item();  
 item.fetch();//執行fetch後,就會自動由server取得資料並存在這個item內  

3.可被監聽
Model內存有多個屬性變數,可以在View上,指定監聽Model的特定屬性,只要當Model的該屬性內容發生變化,View內設定的function即會被觸發執行

 var model=new Backbone.Model({  
      x:123,  
      y:456  
 })   
 var myModel=new Backbone.Model({  
      x:123,  
      y:456  
 })       
 var view=new Backbone.View({  
   model:myModel,  
   initialize:function(){  
      model.on('change:x',this.onChangeHandler)  
   },  
   onChangeHandler:function(){  
   }  
 })  
4.使用模式
我們通常可以將App的Status變化,以不同的變數儲存在model內,然後讓需要因為App Status變化,而有需要改變的View監聽這個model,即可讓App內的View可以自動依照status狀態不同而改變,在這樣狀況下使用的model不需要與Server溝通,只是把model當作變數物件使用,再利用model可以被監聽的特性來使用。

model也會被當作由Server端取得資料後,要儲存在Client上的最小儲存單位。
當由Server上取得多筆的資料,每一筆資料都會用model物件型態來儲存,所有的model再放到collection內來儲存,client端的程式就操作這collection即可。