13

クライアントにRESTful APIを提供するRailsサーバーアプリとして設計されたアプリを構築しています。Rails サーバーは RABL を使用します。クライアントは、標準の $http 呼び出し (gets、puts など) を実行する Angular JS クライアントです。

ときどき、Rails サーバーがエラー (オブジェクトに関連付けられた検証エラーとしましょう) を生成するか、エラーが発生しないことさえあります。この場合、ユーザーに何かを表示したいと思います。たとえば、「レコードが保存されませんでした... 」または「レコードは正常に更新されました」。

これを処理するために、Rails 側と Angular/クライアント側の両方でパターンを作成しようとしています。

Railsに関しては:

  • エラー配列を含めるために、各 RABL ファイルのノードを確実に返すことができます。
  • 戻る前にコントローラーをチェックインすることで、別の RABL を返すこともできます
  • ほとんどの人は、こちらのように http コード (これは理にかなっています) を使用することを提案しています (ただし、検証エラーのようなコードの一貫した使用法はないようです)。

角度に関しては:

ここで車輪を再発明する必要がなく、誰かが現在使用され、提案されている (そしてローカライズされている) パターンを教えてくれることを望んでいると思います。

4

2 に答える 2

12

私は先に進み、実行する必要があると思ったことを実行しました。これについて助けてくれたdigger69に感謝します。

Rails 側では、http ステータス コードを使用しました。hereに従って、エラー検証に 400 http ステータス コードを使用することに同意しました。

私のコントローラーには、次のようなものがあります。

def create
  my_obj = MyObj.build_with_params(params)
  if my_obj.save
    respond_with(my_obj) # regular RABL response
  else
    respond_with_errors(my_obj.errors)
  end
end

私のapplication_controller.rbで、一般的なメソッドrespond_with_errorsを定義しました

# respond back to the client an http 400 status plus the errors array
def respond_with_errors(errors)
  render :json => {:errors => errors}, :status => :bad_request
end

:bad_request シンボルは、こちらのように Rails に対して既に定義されていることに注意してください。

クライアント側では、http 呼び出しをインターセプトする必要がありました (検証だけでなく、認証の失敗も (おそらくそれ以上))。Angular でのコードの例を次に示します (この投稿の助けに感謝します)。

var interceptor = ['$rootScope', '$q', function (scope, $q) {
  function success(response) {
    return response;
  }
  function error(response) {
    var status = response.status;

    if (status == 401) { // unauthorized - redirect to login again
      window.location = "/";
    } else if (status == 400) { // validation error display errors
      alert(JSON.stringify(response.data.errors)); // here really we need to format this but just showing as alert.
    } else {
      // otherwise reject other status codes
      return $q.reject(response);
    }
  }
  return function (promise) {
    return promise.then(success, error);
  }
}];
$httpProvider.responseInterceptors.push(interceptor);

これで、Rails コードと一貫性を保つことができ、クライアントでの http 呼び出しからの成功の戻り値を処理できるようになりました。もっとやるべきことがあると思いますが、これでローカライズされた解決策が得られると思います。

于 2013-04-11T21:20:45.960 に答える
1

HTTP 応答インターセプターを使用します。私は現在、アプリケーションでそれをうまく使用しています。

http://docs.angularjs.org/api/ng.$http

ドキュメントから:

$provide.factory('myHttpInterceptor', function($q, dependency1, dependency2) {
  return function(promise) {
    return promise.then(function(response) {
      // do something on success
    }, function(response) {
      // do something on error
      if (canRecover(response)) {
        return responseOrNewPromise
      }
      return $q.reject(response);
    });
  }
});

$httpProvider.responseInterceptors.push('myHttpInterceptor');

私の場合、成功メッセージまたはエラー メッセージをグローバルに表示するフィードバック サービスを作成しました。別のオプションは、ルートスコープで応答をブロードキャストすることです。

于 2013-04-11T21:00:25.793 に答える