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/cn.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