13

我正在构建一个应用程序,它被构建为 Rails 服务器应用程序,为客户端提供 RESTful api。Rails 服务器使用 RABL。客户端是执行标准 $http 调用(gets、puts 等)的 Angular JS 客户端。

有时,我的 Rails 服务器会产生错误(假设附加到对象的验证错误)甚至没有错误,在这种情况下我想向用户显示一些东西 - 要么是错误,例如,“记录没有保存,因为...... " 或 "记录已成功更新"。

我试图在 Rails 端和 Angular/客户端都绘制出一个模式来处理这个问题。

至于导轨:

  • 我当然可以在每个 RABL 文件中传回一个节点以包含错误数组
  • 我还可以通过在返回前签入控制器来返回不同的 RABL
  • 大多数人建议按照此处使用http代码(这是有道理的) (尽管对于验证错误之类的代码似乎没有一致的用法)。

至于角:

  • 我想我可以编写一个响应拦截器,但不确定如何完全清除它。

我想我希望我不必在这里重新发明轮子,有人可以指出我当前使用和建议(和本地化)的模式。

4

2 回答 2

12

我继续执行我认为需要做的事情。感谢digger69 对此的帮助。

在 Rails 方面,我使用了 http 状态码。根据这里,我同意使用 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

请注意,已根据此处为 Rails 定义了 :bad_request 符号

在客户端,我需要拦截 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');

在我的例子中,我创建了一个反馈服务,它在全局范围内显示成功或错误消息。另一种选择是在 rootscope 上广播响应。

于 2013-04-11T21:00:25.793 回答