【问题标题】:AngularJS - $http POST with Rails 3.2.3AngularJS - 带有 Rails 3.2.3 的 $http POST
【发布时间】: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 = "";
            })
        }

【问题讨论】:

    标签: javascript jquery ruby-on-rails-3 angularjs


    【解决方案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",请将&lt;your app name&gt; 替换为MyAppName
    • &lt;list of modules needed by this app&gt; 需要替换为以逗号分隔的字符串列表,表示您的应用程序所需的任何模块。

    【讨论】:

    • 不应该把Contacts注入控制器吗?
    • @DominicMitchell,是的。懒得提了。将编辑答案以将联系人注入控制器。感谢您指出。
    • @Sathish - 非常感谢您的帮助。我实现了您的代码,并且收到联系人的“未知提供者”错误。我在原始帖子的底部创建了一个更新部分,其中包含更多详细信息。
    • @Sathish - 划掉最后一条评论。现在一切都很好,感谢您对服务的帮助。
    【解决方案2】:

    检查您模型上的attr_accessible。有了新的 3.2.3 rails,所有模型属性都默认受到保护,不会被批量分配。

    【讨论】:

    • 感谢马克的反馈。不过,我认为这不是问题所在,因为我的所有模型属性都列在 attr_accessible 帮助器之后。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-08
    • 2011-08-27
    • 1970-01-01
    • 1970-01-01
    • 2019-07-03
    • 1970-01-01
    相关资源
    最近更新 更多