2012-03-22 66 views
83

我更喜歡前端開發,並且最近開始將Backbone.js瀏覽到我的應用程序中。我想將模型數據保存到服務器。如何保存Backbone.js模型數據?

請您向我解釋保存模型數據的各種方式(使用json格式)。我在服務器端使用Java。另外我主要看到REST被用來保存數據。由於我更喜歡​​前端開發,我不知道REST和其他類似的東西。

如果有人能用一個簡單的例子來解釋我的過程,那將是非常棒的。

回答

266

基本上模型有一個叫屬性的屬性,它是某個模型可能具有的各種值。 Backbone使用JSON對象作爲一種簡單的方式來使用帶有JSON對象的各種方法來填充這些值。例如:

Donuts = Backbone.Model.extend({ 
    defaults: { 
     flavor: 'Boston Cream', // Some string 
     price: '0.50' // Dollars 
    } 
}); 

要填充模型有幾種方法可以這樣做。例如,您可以通過傳入JSON或使用名爲set()的方法來設置模型實例,該方法接受屬性的JSON對象。

myDonut = new Donut({'flavor':'lemon', 'price':'0.75'}); 
mySecondHelping = new Donut(); 
mySecondHelping.set({'flavor':'plain', 'price':'0.25'}); 

console.log(myDonut.toJSON()); 
// {'flavor':'lemon', 'price':'0.75'} 
console.log(mySecondHelping.toJSON()); 
// {'flavor':'plain', 'price':'0.25'} 

因此,這帶來了我們保存模型和堅持他們要麼服務器。有關「什麼是REST/RESTful?」的詳細信息有很多在這裏短暫的講話中解釋這一切有點困難。特別是關於REST和Backbone的保存,頭腦中的東西就是HTTP請求的語義以及你對數據的處理。

您可能已經習慣了兩種HTTP請求。 GET和POST。在RESTful環境中,這些動詞對Backbone假定的特定用途具有特殊意義。當您想要從服務器獲取特定資源(例如,上次保存的甜甜圈模型,博客條目和計算機規範)並且該資源存在時,您將執行GET請求。相反,當你想創建一個新的資源時,你使用POST。

在我進入Backbone之前,我甚至從來沒有碰過以下兩種HTTP請求方法。 PUT和DELETE。這兩個動詞對Backbone也有特定的含義。當您想要更新資源時(例如,將檸檬甜甜圈的味道改爲檸檬甜甜圈等),您可以使用PUT請求。當您想要一起從服務器刪除該模型時,您使用DELETE請求。

這些基礎知識非常重要,因爲使用REST風格的應用程序時,您可能會擁有一個URI名稱,它將根據您使用的請求動詞的種類執行相應的任務。例如:

// The URI pattern 
http://localhost:8888/donut/:id 

// My URI call 
http://localhost:8888/donut/17 

如果我做一個GET到URI,它會得到甜甜圈模型的17.一個ID:ID取決於你如何保存它的服務器端。這可能只是您的數據庫表中您的甜甜圈資源的ID。

如果我用新數據對該URI進行PUT,我會更新它,並保存在該URI上。如果我刪除到該URI,那麼它會從我的系統中清除它。

對於POST,由於您尚未創建資源,因此它將不具有已建立的資源ID。也許我想創建資源的URI目標是這樣的:

http://localhost:8888/donut 

URI中沒有ID片段。所有這些URI設計都由您決定,您如何看待您的資源。但就RESTful設計而言,我的理解是,您希望將對HTTP請求和資源的操作動詞保持爲使URI容易閱讀和人性化的名詞。

你還在我身邊嗎? :-)

那麼讓我們回過頭來思考Backbone。骨幹是美好的,因爲它爲你做了很多工作。爲了節省我們的甜甜圈和第二次幫助,我們只是這樣做:

myDonut.save(); 
mySecondHelping.save(); 

骨幹很聰明。如果您剛剛創建了甜甜圈資源,它將不會有服務器的ID。它有一個叫做cID的東西,這是Backbone在內部使用的東西,但由於它沒有正式的ID,它知道它應該創建一個新的資源併發送一個POST請求。如果你從服務器獲得你的模型,如果一切正常,它可能會有一個ID。在這種情況下,當你保存時()Backbone假定你想更新服務器,它會發送一個PUT。要獲取特定的資源,您需要使用Backbone方法.fetch()併發送GET請求。當您在模型上調用.destroy()時,它將發送DELETE。

在前面的例子中,我從來沒有明確告訴骨幹URI的位置。我們在下一個例子中這樣做。

thirdHelping = Backbone.Model.extend({ 
    url: 'donut' 
}); 
thirdHelping.set({id:15}); // Set the id attribute of model to 15 
thirdHelping.fetch(); // Backbone assumes this model exists on server as ID 15 

骨幹會得到http://localhost:8888/donut/15的thirdHelping它會簡單地添加/甜甜圈幹到您的網站的根。

如果你仍然和我在一起,很好。我認爲。除非你感到困惑。但我們仍然會跋涉。第二部分是SERVER端。我們討論了HTTP的不同動詞以及這些動詞背後的語義含義。意思是你,骨幹和你的服務器必須共享。

您的服務器需要了解GET,POST,PUT和DELETE請求之間的區別。正如你在上面的例子中看到的那樣,GET,PUT和DELETE都可以指向相同的URI http://localhost:8888/donut/07除非你的服務器能夠區分這些HTTP請求,否則對於如何處理這個資源會很困惑。

這是當你開始考慮你的RESTful服務器端代碼。有些人喜歡Ruby,有些人喜歡.net,我喜歡PHP。特別我喜歡SLIM PHP微型框架。 SLIM PHP是一個微型框架,它具有用於處理RESTful活動的非常優雅和簡單的工具集。您可以像上述示例中那樣定義路由(URI),並根據調用是GET,POST,PUT還是DELETE來執行正確的代碼。還有其他類似SLIM的解決方案,如Recess,Tonic。我相信像Cake和CodeIgniter這樣的更大的框架也可以做類似的事情,儘管我很喜歡。我說我喜歡Slim嗎? ;-)

這是在服務器上摘錄的代碼可能是什麼(即專門與路徑。)

$app->get('/donut/:id', function($id) use ($app) { 
    // get donut model with id of $id from database. 
    $donut = ... 

    // Looks something like this maybe: 
    // $donut = array('id'=>7, 'flavor'=>'chocolate', 'price'=>'1.00') 

    $response = $app->response(); 
    $response['Content-Type'] = 'application/json'; 
    $response->body(json_encode($donut)); 
}); 

這裏要注意的是骨幹網需要一個JSON對象,這一點很重要。如果可以,請始終讓服務器將內容類型指定爲「application/json」並以json格式對其進行編碼。然後,當Backbone接收到JSON對象時,它知道如何填充請求它的模型。

使用SLIM PHP,路線的操作與上述非常類似。

$app->post('/donut', function() use ($app) { 
    // Code to create new donut 
    // Returns a full donut resource with ID 
}); 
$app->put('/donut/:id', function($id) use ($app) { 
    // Code to update donut with id, $id 
    $response = $app->response(); 
    $response->status(200); // OK! 
    // But you can send back other status like 400 which can trigger an error callback. 
}); 
$app->delete('/donut/:id', function($id) use ($app) { 
    // Code to delete donut with id, $id 
    // Bye bye resource 
}); 

所以你差不多完成了全程!去買蘇打水吧。我喜歡Diet Mountain Dew。也爲我取一個。

一旦你的服務器處理了一個請求,對數據庫和資源做了一些事情,準備了一個響應(無論它是一個簡單的http狀態號還是完整的JSON資源),那麼數據將返回到Backbone進行最終處理。

與您保存(),取()等方法 - 你可以在成功和錯誤添加可選的回調。這裏是我如何設置這個特殊的蛋糕的例子:

Cake = Backbone.Model.extend({ 
    defaults: { 
     type: 'plain', 
     nuts: false 
    }, 
    url: 'cake' 
}); 

myCake = new Cake(); 
myCake.toJSON() // Shows us that it is a plain cake without nuts 

myCake.save({type:'coconut', nuts:true}, { 
    wait:true, 
    success:function(model, response) { 
     console.log('Successfully saved!'); 
    }, 
    error: function(model, error) { 
     console.log(model.toJSON()); 
     console.log('error.responseText'); 
    } 
}); 

// ASSUME my server is set up to respond with a status(403) 
// ASSUME my server responds with string payload saying 'we don't like nuts' 

這個例子有幾個不同的東西。你會看到我的蛋糕,而不是保存前設置()的屬性,我只是將新的屬性傳遞給我的保存調用。骨幹是相當忍者在所有地方採取JSON數據和處理它像一個冠軍。所以我想用椰子和堅果保存我的蛋糕。 (這是2個堅果?)無論如何,我通過兩個對象來保存。屬性JSON對象和一些選項。第一個,{wait:true}表示在服務器端行程成功之前不更新我的客戶端模型。成功回調將在服務器成功返回響應時發生。但是,由於此示例導致錯誤(200以外的狀態將指示Backbone使用錯誤回調),因此我們可以在沒有更改的情況下獲得模型的表示。它應該是平淡無味的。我們也可以訪問服務器發回的錯誤對象。我們發回了一個字符串,但它可能是具有更多屬性的JSON錯誤對象。這位於error.responseText屬性中。是的,'我們不喜歡堅果。'

恭喜。您從建立模型開始您的第一次非常完整的往返旅程,將其保存在服務器端並返回。我希望這個回答史詩給你一個關於這一切如何結合在一起的想法。當然有很多細節我正在巡航過去,但Backbone保存,RESTful動詞,服務器端操作,響應的基本概念都在這裏。繼續閱讀Backbone文檔(與其他文檔相比,它非常容易閱讀),但請記住,這需要時間來包裝頭部。你越留在它上面,你會越流利。我每天都會通過Backbone學到一些新東西,當你開始飛躍並看到你在這個框架中的流暢度不斷提高時,它會變得非常有趣。 :-)

快樂編碼!

編輯:資源可能是有用的:在SO

其他類似的答案: How to generate model IDs with Backbone

在休息: http://rest.elkstein.org/ http://www.infoq.com/articles/rest-introduction http://www.recessframework.org/page/towards-restful-php-5-basic-tips

+8

我最終會在這一點堅果。我記得當我第一次開始Backbone時,有問題像提問者那樣,而且我寫了一些迴應有點太多樂趣了。我敢肯定,在我匆忙中,我犯了一些錯誤,或錯過了一些重要的批評「啊哈!」如果我這樣做,讓我知道。 :-P – jmk2142 2012-03-25 17:05:23

+5

回答說至少是......我正在努力把握你所提到的所有事情。儘管你是對的,但REST事情看起來有點困難,但你不能在這個問題中解釋我REST。 ..我會再次通過這些事情,並在一段時間內接受它... Thx再次爲詳細的答案... – testndtv 2012-03-25 17:51:58

+2

當我得到時間,我會更新我的答案與一個很好的參考名單,可以幫助你在追求。我不能給你一把木劍來面對危險的世界,但我可以給你幫助我的網站的資源鏈接。 :-) – jmk2142 2012-03-25 18:09:32