AngularJS - 带有 Rails 3.2.3 的 $http POST
Posted
技术标签:
【中文标题】AngularJS - 带有 Rails 3.2.3 的 $http POST【英文标题】:AngularJS - $http POST with Rails 3.2.3 【发布时间】:2012-05-20 10:30:05 【问题描述】:我正在使用 AngularJS 1.0.0rc8 和 Crud 构建一个简单的联系人管理应用程序。
获取当前存在的联系人列表没有问题,但是在尝试将新联系人保存到服务器时,会创建一个新行 - 包含正确的 id、created_at 和 updated_at 值 - 但其余模型数据被忽略。
这是一个屏幕截图来说明我的意思:
如您所见,数字 4 和 5 被赋予了 ID,但 first_name、last_name 和 phone_num 并未保存到数据库中。
我在控制器中使用 $scope.addContact 函数来处理对象。
这是联系人列表控制器的完整代码:
'use strict';
function ContactListCtrl($scope, $http)
$http.get('/contacts').success(function(data)
$scope.contacts = data;
);
$scope.addContact = function(data)
$http.post('/contacts/', data).success(function(data)
console.log(data);
data.first_name = $("#new_contact_first_name").val();
data.last_name = $("#new_contact_last_name").val();
);
this.newFirstName = '';
this.newLastName = '';
;
;
在 new-contact.html 部分单击 'Save' 后,对象会记录到控制台,如果我检查其内容,那么肯定会收集值 - 请注意 Jimi Hendrix 是那里:
这是 new-contact.html 模板中显示的表单:
<form id="contact_form" ng-submit="addContact()">
<input type="text" id="new_contact_first_name" name="newContactFirstName" ng-model="newFirstName" placeholder="First Name"></br>
<input type="text" id="new_contact_last_name" name="newContactLastName" ng-model="newLastName" placeholder="Last Name"></br>
<input type="button" id="contact_submit_btn" value="Add Contact" class="btn btn-primary">
</form>
addContact() 函数在使用 JQuery 提交表单后触发:
$(document).ready(function()
$("#contact_submit_btn").click(function()
$("#contact_form").submit();
);
);
(有些东西告诉我,我可能没有正确使用 ng-model 属性。)
关于我在哪里出错的任何想法?或者关于如何更好地实施此设计的想法?
谢谢。
以下更新:
这是我更新后的完整控制器代码 - 在 Sathish 的帮助下:
// contacts controllers
'use strict';
function ContactListCtrl($scope, $http, Contacts)
$scope.contacts = Contacts.index();
$scope.addContact = function()
var newContact =
first_name: $scope.newContactFirstName,
last_name: $scope.newContactLastName
;
var nc = new Contacts( contact: newContact );
nc.$create(function()
$scope.contacts.push(nc);
// now that the contact is saved, clear the form data
$scope.newContactFirstName = "";
$scope.newContactLastName = "";
)
;
ContactListCtrl.$inject = ['$scope', '$http', 'Contacts'];
function ContactDetailCtrl($scope, $routeParams, Contacts)
$scope.contact = Contacts.get( contact_id: $routeParams.contact_id );
ContactDetailCtrl.$inject = ['$scope', '$routeParams', 'Contacts'];
我现在收到错误消息:未知的联系人提供程序。这是错误的截图
好的,我设法通过向主 App 文件提供 ngResource 来修复该错误。这是它的样子:
// main app javascript file
'use strict';
angular.module('contactapp', ['ngResource']).
config(['$routeProvider', function($routeProvider)
$routeProvider.
when('/contacts', template: 'assets/app/partials/contact-list.html', controller: ContactListCtrl).
when('/contacts/new', template: 'assets/app/partials/new-contact.html', controller: ContactListCtrl).
when('/contacts/:contact_id', template: 'assets/app/partials/contact-detail.html', controller: ContactDetailCtrl).
otherwise(redirectTo: '/contacts');
]);
我收到一个新错误:警告:无法验证 CSRF 令牌的真实性
好的,通过向 API 控制器添加回调也设法解决了这个问题: Rails shows "WARNING: Can't verify CSRF token authenticity" from a RestKit POST
现在我回到原来的问题。调用 create 方法时,会在数据库中保存一个新行,但模型数据不会。
太棒了……终于搞定了。
问题出在 $scope.addContact 函数上。它使用输入的“名称”而不是位于模板中的名为“newFirstName”和“newLastName”的 ng-model 绑定。
更新后的函数如下所示:
$scope.addContact = function()
var newContact =
first_name: $scope.newFirstName,
last_name: $scope.newLastName
;
var nc = new Contacts( contact: newContact );
nc.$create(function()
$scope.contacts.push(nc);
// now that the contact is saved, clear the form data
$scope.newFirstName = "";
$scope.newLastName = "";
)
【问题讨论】:
【参考方案1】:使用联系人服务可以更好地实现这一点。请在 app/assets/javascripts/services.js.erb 中定义一个 Contacts 服务,如下所示:
var servicesModule = angular.module('<your app name>',
[<list of modules needed by this app>]);
servicesModule.factory('Contacts', function($resource)
var ContactsService = $resource('/contacts/:contact_id', ,
'create': method: 'POST' ,
'index': method: 'GET', isArray: true ,
'update': method: 'PUT' ,
'destroy': method: 'DELETE'
);
return ContactsService;
);
改变控制器中的addContact方法如下图:
function ContactListCtrl($scope, $http, Contacts)
...
...
...
$scope.addContact = function ()
var newContact =
first_name: $scope.newContactFirstName,
last_name: $scope.newContactLastName
;
var nc = new Contacts( contact: newContact );
nc.$create(function()
$scope.contacts.push(nc);
// now that the contact is saved, clear the form data.
$scope.newContactFirstName = "";
$scope.newContactLastName = "";
);
;
...
...
...
ContactListCtrl.$inject = ['$scope', '$http', 'Contacts'];
除此之外,您还可以简化$http.get(...)
部分。你可以使用Contacts.index();
注意:
如果您提供了ng-app="MyAppName"
,请将<your app name>
替换为MyAppName
。
<list of modules needed by this app>
需要替换为以逗号分隔的字符串列表,表示您的应用程序所需的任何模块。
【讨论】:
不应该把Contacts注入控制器吗? @DominicMitchell,是的。懒得提了。将编辑答案以将联系人注入控制器。感谢您指出。 @Sathish - 非常感谢您的帮助。我实现了您的代码,并且收到联系人的“未知提供者”错误。我在原始帖子的底部创建了一个更新部分,其中包含更多详细信息。 @Sathish - 划掉最后一条评论。现在一切都很好,感谢您对服务的帮助。【参考方案2】:检查您模型上的attr_accessible
。有了新的 3.2.3 rails,所有模型属性都默认受到保护,不会被批量分配。
【讨论】:
感谢马克的反馈。不过,我认为这不是问题所在,因为我的所有模型属性都列在 attr_accessible 帮助器之后。以上是关于AngularJS - 带有 Rails 3.2.3 的 $http POST的主要内容,如果未能解决你的问题,请参考以下文章
rails + angularjs 在编辑时将值加载到文本字段中