2

私は AngularJS の初心者で、AngularJS で POST リクエストを作成しようとすると問題に直面しましたが、パラメーターが POST されません。RESTful インターフェイスとして Sinatra を使用しています。

それが私の Sinatra バックエンドの外観です。

post '/layer/:layer_id' do
  @layer = PageLayer.where(id: params[:layer_id]).first
  @layer.content = params[:content]
  @layer.save
end

Postman chrome 拡張機能を使用して POST しようとすると、動作します! シナトラはコンテンツを適切に保存します。したがって、バックエンドが正常に機能していると確信しています。

それが私のAngularテストコードの外観です:

TestCtrl = ($scope, $routeParams, $http, $resource) ->
    $scope.layer = []

    Layer = $resource('/layer/:id', {id:'@id'})

$scope.layer = Layer.get {id: $routeParams.layerId}, ->
    console.log "Got you!"

$scope.saveContent = ->
    $scope.layer.$save()
    console.log "Saved!"

angular.module('appDirectives', []).directive "test", ->
    return (scope, element, attrs) ->
        element.bind "blur", ->
            console.log("blur!")
            scope.saveContent()

そしてHTMLコード:

<div>Content: {{layer.content}}</div>

<div>
    <form>
        <input type="text" test ng-model="layer.content">
    </form>
</div>

だから、唯一の質問は:何が問題なのですか?なぜ私は Postman で正しいリクエストを行うことができますが、angularJS ではできませんか? Angular は空の「コンテンツ」を返すので、Sinatra は毎回それを「」として保存します。

レイヤーの構造も添付しました。

g {id: 27245, page_id: 2302, external_id: 26518, original_upload: null…}
content: "dfgdfg"
external_id: 26518
id: 27245
layerNumber: 8
page_id: 2302

どの角度の POST を正確にログに記録するにはどうすればよいですか?

4

3 に答える 3

4

ねえ、これは私が抱えていた正確な問題であり、答えは今ではとても明白なようです. Angular が json を送信していることは知っていましたが、何を試しても機能しませんでした。これは正しい方向に私を導きましたが、jsonの解析に関しては私は書かなければなりませんでした

ng_params = JSON.parse(request.body.read)

「文字列」を「読み取り」に変更する必要がありました。多分私はjson gemか何かの新しいバージョンを持っています。私の完全な保存プロセスは次のとおりです。

post '/api/v1/test' do
  ng_params = JSON.parse(request.body.read)
  @foo = Foo.new(ng_params)
  if @foo.save
    puts "Page Saved"
    content_type :json
    rabl :foos, format: "json"
  end
end

rabl を使用して json をフォーマットし、Sinatra が返す json データを制御します (メールやパスワードは不要です)。

私のAngularコードはこれだけです(まだput、patch、delete、データの自動更新を実装していません。新しい投稿を表示するには、ページを更新する必要があります。)そして明確にするために、「 ActiveRecord モデルが 'Foo' で、1 つの列に 'anything' という名前が付けられています (タイムスタンプと ID を除く。これらは常に存在することを確認しています)。

// app declaration
var app = angular.module("App", ['ngResource']);

// data service
app.factory('Foo', ['$resource', function($resource) {
  return $resource('/api/v1/test/:id', {id: '@id'});
}]);

// the controller
app.controller('Controller', function($scope, Foo) {

  $scope.foos = Foo.query();

  $scope.create = function(anything) {
    Foo.save({anything: anything}, function(foo){
      $scope.foos.push(foo);
    });
  };
});

次に、私のマークアップでは、フォームは次のようになります。ここで重要なのは、「ng-submit」の引数として「anything」を使用して「create」を呼び出すことです。テーブルに複数の列がある場合は、複数の引数を指定して「作成」を呼び出します。「作成(なんでも、バー)」。

<h3>Add something new</h3>
<form ng-submit="create(anything)">
  <input ng-model="anything" type="text">
  <button type="submit">Do it</button>
</form>

データを表示している間、

<li ng-repeat="foo in foos">
  <p>{{foo.anything}}</p>
</li>
于 2013-10-31T21:15:38.483 に答える
2

このリンクは問題を解決しました。追加するだけ

gem「ラックパーサー」

Gemfileに追加し、このコードをconfig.ru に追加します魔法のように機能します。

require 'rack/parser'
use Rack::Parser, content_types: {
  'application/json' => Proc.new {|body| JSON.parse body }
}
于 2014-12-18T12:25:21.250 に答える
1

問題は解決しました。どういうわけか、Sinatra は Angular から POST を適切に取得しておらず、それらを自動的に params に入れていませんでした。したがって、リクエストを手動で解析すると、機能します。そのように:

post '/layer/:layer_id' do
  @updated_layer = JSON.parse(request.body.string)
  @layer = PageLayer.where(id: params[:layer_id]).first
  @layer.content = @updated_layer['content']
  @layer.save 
end 
于 2013-08-15T07:57:22.650 に答える