Web_Design 板


LINE

我最近在做 Rails + Angular CRUD , 我是 Rails 寫很久最近開始寫 Angular, 我想我可以分享一些經驗。 首先你要把 Angular CRUD 和 Rails CRUD 分開來看, Angular 的資料不管怎麼改,都是存在前端的 JavaScript 的記憶體裡面, 沒有後送到 Server 的話 Server 都不知道。 Angular 做為一個前端 framework 是不需要管後端怎麼做的, 在拿資料的時候是用 JSON 拿沒錯,但存回 server 的時候還是得用 Ajax 打回去。 具體的做法是這樣: // in controller $http.post("/articles", { title: "New Article 1", content: "..." }) .then(function(response) { /* 存好了 */ }); 打開 Chrome 的 Inspector 的 Network ,你會看到有個 request 過去。 那麼,既然都用 Ajax 存資料到後端了,取得資料當然也用 Ajax 做: $http.get("/articles/1") .then(function(response) { $scope.article = response; } 後端出 JSON 用 respond_with 你應該不陌生。 到這裡為止,你可以參考 Angular 官方的 Tutorial "PhoneCat" http://docs.angularjs.org/tutorial/step_00 它會一步一步教到用 $resource 來跟後端 RESTful Server 存取資料。 不過呢,預設的 Angular $http 是沒辦法接上 Rails 的 原因有二,一個是 $http 少送一個 header 叫 X-Requested-With=XMLHttpRequest 大部份的 Ajax Library 都有送,就它沒送,所以它認不出 POST by Ajax。 所以要去偷改 $httpProvider: app.config([ '$httpProvider', function($httpProvider) { $httpProvider.defaults.headers .common["X-Requested-With"] = "XMLHttpRequest"; } ]); 這樣 Rails 就能正確解出 POST by Ajax 了。 第二個是 CSRF Token 的傳法 Rails 一般的表單做法是藏在 Form 裡面有個 hidden input, Rails 傳統的 Ajax 用 UJS 會自動讀 meta 裡面的 CSRF Token 但 Angular 是用 Header 傳,並且取第一次連線時的 cookie['XSRF-TOKEN'], 於是你要 hack 一下 controller 讓它送出這個 cookie 並且讓 Rails 去認 Angular 傳來的 Token in Header 詳細:http://stackoverflow.com/a/15761835 最後是關於 $resource 的一些 caveats $resource 跟 restangular 我都用過, 最後是覺得後者的 DSL 太難記,前者就單純是 CRUD ,比較好學。 首先是 Rails 的 "Update" 通常是 PATCH 或 PUT, 所以官方文件裡面的範例的 article.$save 在 Rails 不太實用(它是送 POST) 在 $resource 裡面要這樣定義(其實文件裡面也有提到): var Article = $resource("/articles/:id", { // default options id: "@id" // 表示自動取用 Article class 的 instance 的 "id" property }, { // custom actions update: { method: "PUT" // 定義 article.$update 送 PUT request } }); 至於存的時候是這樣存: // 先更新 JavaScript 物件的資料 $scope.article.title = "New Title"; // 或是 ng-model 綁到 input $scope.article.content = "New Content"; // 戳 "update" button 的時候 $scope.article.$update .then(function(article) { // Rails 傳回 show.json // 然後一個一個欄位更新 // 不要直接 $scope.article = article,不然會變成不是 $resource 的物件 for (var property in article) { if (article.hasOwnProperty(property)) { $scope.article[property] = article[property]; } }, function(response) { // 儲存失敗,Rails 直接 render :json => { :errors => @article.errors } $scope.errors = response.data.errors; // 然後你在 view 裡面用 ng-if 去 render errors }); 如果是 nested 的場合是這樣: var Comment = $resource("/articles/:articleId/comments/:id", { id: "@id", articleId: $scope.article.id }, { // 略 }); 也配合 ng-route 或 Angular UI-Router 可以從 #/ 裡面取得 article id 。 custom member action 的做法是這樣(以「把某噗靜音」為例): var Plurk = $resource("/plurks/:id/:action", { id: "@id", action: "" // 預設把 action 填空字串 }, { mute: { method: "POST", params: { action: "mute" // 把 action 填入 "mute" } } }); 這樣子 plurk.$mute() 就會送出 POST /plurks/123/mute 了。 但 $resource 如果要對 collection 做 custom action 會很難處理, 因為 $resource 不像 Rails 的 routes.rb 可以定義 collection 和 member action, 而且話說回來 Rails 的 router 處理 collection action 本來就是跟 id 多載, 所以我看到 Stack Overflow 上面有人的做法是這樣: // 以「把所有的噗都設為已讀」(MAAR) 為例 var Plurk = $resource("/plurks/:id:collectionAction/:memberAction", { id: "@id", collectionAction: "", memberAction: "" }, { maar: { method: "POST", params: { id: "", collectionAction: "maar" } } }); 這樣很醜,但似乎很多人都是這樣寫的,不過我實際上沒寫過就是了。 ※ 引述《lisaweng (piglet)》之銘言: : 最近在學AngularJs 不知道各位大大有沒有學過 : 後端是用rails寫的 : 面臨到的問題是 : 一開始view那邊我都是用angularJs從rails拿data : 把.JSON的資料存到變數 : 然後再顯示在網頁上 : 可是發現這樣好像就沒怎麼到two way data binding : 所以請問這樣我在做的時候也是要在AngularJS建資料嗎 : 例如說假設我現在在做一個部落格 : 我現在的做法是 : 每當我在點"Create Article" 我的文章就會存在rails那邊 : 然後當我要顯示那個文章的時候。我必須去讀那個文章的.JSON : 可是這樣好像不太效率 : 是不是我應該要改成我每一次點Create Article的時候 : 要把資料同時存在rails和js呢? : 然後讀的時候可以直接從js讀? : 謝謝! --



※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 36.231.18.230
※ 文章網址: http://webptt.com/m.aspx?n=bbs/Web_Design/M.1397743476.A.7C2.html ※ 編輯: ducksteven (36.231.18.230), 04/17/2014 22:06:28 ※ 編輯: ducksteven (36.231.18.230), 04/17/2014 22:09:45 ※ 編輯: ducksteven (36.231.18.230), 04/17/2014 22:11:17 ※ 編輯: ducksteven (36.231.18.230), 04/17/2014 22:14:22 ※ 編輯: ducksteven (36.231.18.230), 04/17/2014 22:18:21
1F:推 sdlong:Xdite: Rails 跟 AngularJS 是無法整合的,別白費力氣 XD 04/18 03:19
2F:推 turtleknight:真多學問...還好我可以用websocket... 04/18 10:38
3F:推 LetDogDay:為什麼不能整合? 04/19 20:07
4F:推 Rplus:推 04/20 01:53
5F:推 a83294:ember會不會比較好 04/21 15:28
6F:推 lisaweng:一直忘記來推文 謝謝你噢 :D 04/29 21:38







like.gif 您可能會有興趣的文章
icon.png[問題/行為] 貓晚上進房間會不會有憋尿問題
icon.pngRe: [閒聊] 選了錯誤的女孩成為魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一張
icon.png[心得] EMS高領長版毛衣.墨小樓MC1002
icon.png[分享] 丹龍隔熱紙GE55+33+22
icon.png[問題] 清洗洗衣機
icon.png[尋物] 窗台下的空間
icon.png[閒聊] 双極の女神1 木魔爵
icon.png[售車] 新竹 1997 march 1297cc 白色 四門
icon.png[討論] 能從照片感受到攝影者心情嗎
icon.png[狂賀] 賀賀賀賀 賀!島村卯月!總選舉NO.1
icon.png[難過] 羨慕白皮膚的女生
icon.png閱讀文章
icon.png[黑特]
icon.png[問題] SBK S1安裝於安全帽位置
icon.png[分享] 舊woo100絕版開箱!!
icon.pngRe: [無言] 關於小包衛生紙
icon.png[開箱] E5-2683V3 RX480Strix 快睿C1 簡單測試
icon.png[心得] 蒼の海賊龍 地獄 執行者16PT
icon.png[售車] 1999年Virage iO 1.8EXi
icon.png[心得] 挑戰33 LV10 獅子座pt solo
icon.png[閒聊] 手把手教你不被桶之新手主購教學
icon.png[分享] Civic Type R 量產版官方照無預警流出
icon.png[售車] Golf 4 2.0 銀色 自排
icon.png[出售] Graco提籃汽座(有底座)2000元誠可議
icon.png[問題] 請問補牙材質掉了還能再補嗎?(台中半年內
icon.png[問題] 44th 單曲 生寫竟然都給重複的啊啊!
icon.png[心得] 華南紅卡/icash 核卡
icon.png[問題] 拔牙矯正這樣正常嗎
icon.png[贈送] 老莫高業 初業 102年版
icon.png[情報] 三大行動支付 本季掀戰火
icon.png[寶寶] 博客來Amos水蠟筆5/1特價五折
icon.pngRe: [心得] 新鮮人一些面試分享
icon.png[心得] 蒼の海賊龍 地獄 麒麟25PT
icon.pngRe: [閒聊] (君の名は。雷慎入) 君名二創漫畫翻譯
icon.pngRe: [閒聊] OGN中場影片:失蹤人口局 (英文字幕)
icon.png[問題] 台灣大哥大4G訊號差
icon.png[出售] [全國]全新千尋侘草LED燈, 水草

請輸入看板名稱,例如:Tech_Job 或 站內搜尋

TOP