【问题标题】:How do I save an Angular form to my ruby on rails backend?如何将 Angular 表单保存到我的 ruby​​ on rails 后端?
【发布时间】:2015-02-09 02:35:21
【问题描述】:

我是 Angular 的新手。我已经尝试了所有我知道的方法,而且 Google 搜索关于这个特定问题的教程很少。这是我尝试的最后一个代码:

index.html

<form ng-submit="addArticle(articles)">
<input type="text" id="title" ng-model="newPost.title">
<input type="text" id="body" ng-model="newPost.body">
<input type="submit" value="Submit">
</form>

文章控制器

app.controller('ArticlesCtrl', function($scope, Article) {
  $scope.articles   = Article.query();
  $scope.newPost     = Article.save();
});

文章服务(rails 后端)

app.factory('Article', function($resource) {
  return $resource('http://localhost:3000/articles');
});

我可以很好地检索数据。但我无法向 rails 后端提交任何新数据。在页面加载时,rails 服务器错误是:

Started POST "/articles" for 127.0.0.1 at 2015-02-08 18:26:29 -0800
Processing by ArticlesController#create as HTML
Completed 400 Bad Request in 0ms

ActionController::ParameterMissing (param is missing or the value is empty: article):
  app/controllers/articles_controller.rb:57:in `article_params'
  app/controllers/articles_controller.rb:21:in `create'

按下提交按钮什么都不做。表单基本上不起作用,页面一加载就在寻找提交。

我理解错误的含义,即它没有从表单接收参数。我不明白在我的控制器和/或表单中应该是什么样子。

我做错了什么,我该如何解决?

【问题讨论】:

    标签: ruby-on-rails angularjs forms


    【解决方案1】:

    Angular 有一个名为services 的功能,它充当应用程序的模型。这是我与 Rails 后端通信的地方:

    services/article.js

    app.factory('Article', function($resource) {
      return $resource('http://localhost:3000/articles/:id', { id: '@id'},
      {
       'update': { method: 'PUT'}
      });
    });
    

    即使最后指定了:id,它也同样适用于直接进入/articles 路径。 id 只会在提供的地方使用。

    剩下的工作进入控制器:

    controllers/articles.js

    app.controller('NewPostCtrl', function($scope, Article) {
      $scope.newPost  = new Article();
    
      $scope.save = function() {
        Article.save({ article: $scope.article }, function() {
          // Optional function. Clear html form, redirect or whatever.
        });
      };
    
    });
    

    最初,我认为通过$resources 提供的save() 函数在某种程度上是自动的。是的,但我用错了。默认的save() 函数最多可以使用四个参数,但似乎只需要将数据传递给数据库。在这里,它知道向我的后端发送POST 请求。

    views/articles/index.html

    <form name="form" ng-submit="save()">
        <input type="text" id="title" ng-model="article.title">
        <input type="text" id="body" ng-model="article.body">
        <input type="submit" value="Submit">
    </form>
    

    正确设置service 后,剩下的就很简单了。在控制器中,需要创建资源的新实例(在本例中为新文章)。我创建了一个新的$scope 变量,其中包含调用我在service 中创建的save 方法的函数。

    请记住,在服务中创建的方法可以任意命名。它们的重要性在于发送的 HTTP 请求的类型。对于任何 RESTful 应用程序尤其如此,因为 GET 请求的路由与 POST 请求的路由相同。

    以下是我找到的第一个解决方案。再次感谢您的回复。他们在我的实验中帮助我了解这是如何工作的!

    原解决方案: 我终于修复了它,所以我将发布我的特定解决方案。但是,我只是在缺乏如何通过角度service 执行此操作的信息的情况下走这条路。理想情况下,服务会处理这种 http 请求。另请注意,在服务中使用$resource 时,它带有一些功能,其中之一是save()。然而,这对我也没有奏效。

    articles.js 控制器

    app.controller('FormCtrl', function($scope, $http) {
    $scope.addPost = function() {
    $scope.article = {
      'article': {
        'title'  : $scope.article.title,
        'body'   : $scope.article.body
      }
    };
    
    // Why can't I use Article.save() method from $resource?
        $http({
            method: 'POST',
            url: 'http://localhost:3000/articles',
        data: $scope.article
        });
    };
    

    });

    由于 Rails 是后端,向/articles 路径发送POST 请求会调用#create 方法。对于我来说,这是一个比我之前尝试的更容易理解的解决方案。

    要理解使用services$resource 让您可以访问save() 函数。但是,我仍然没有揭开如何在这种情况下使用它的神秘面纱。我选择了$http,因为它的功能很明确。

    Sean Hill 有一个推荐,这是我今天第二次看到的。它可能对其他任何与此问题搏斗的人有所帮助。如果我遇到使用服务的解决方案,我会更新它。

    感谢大家的帮助。

    【讨论】:

      【解决方案2】:

      我在 Angular 和 Rails 方面做了很多工作,我强烈推荐使用 AngularJS Rails 资源。它使使用 Rails 后端变得更加容易。

      https://github.com/FineLinePrototyping/angularjs-rails-resource

      您需要在应用的依赖项中指定此模块,然后您需要将您的工厂更改为如下所示:

      app.factory('Article', function(railsResourceFactory) {
        return railsResourceFactory({url: '/articles', name: 'article');
      });
      

      基本上,根据您收到的错误,正在发生的事情是您的资源没有创建正确的article 参数。 AngularJS Rails Resource 会为你做这件事,它还负责其他特定于 Rails 的行为。

      此外,$scope.newPost 不应为 Article.save()。您应该改为使用新资源 new Article() 对其进行初始化。

      【讨论】:

        【解决方案3】:

        在您的输入字段为空之前,模型中不会存储任何值并且您发布空文章对象。您可以通过创建客户端验证或在保存之前在所需字段上设置默认空字符串值来修复它。

        首先你应该在范围变量中创建新的 Article 对象,然后通过参数传递newPost 或直接访问$scope.newPost in addArticle fn:

        app.controller('ArticlesCtrl', function($scope, Article) {
          $scope.articles   = Article.query();
          $scope.newPost    = new Article();
        
          $scope.addArticle = function(newPost) {
            if (newPost.title == null) {
              newPost.title = '';
            }
            // or if you have underscore or lodash:
            // lodash.defaults(newPost, { title: '' });
            Article.save(newPost);
          };
        });
        

        如果你想使用 CRUD 操作,你应该像下面这样设置资源:

        $resource('/articles/:id.json', { id: '@id' }, { 
          update: {
            method: 'PUT'
          }
        });
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-03-20
          • 1970-01-01
          • 1970-01-01
          • 2019-05-16
          • 1970-01-01
          • 2020-06-24
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多