angularjs - Restangular错误拦截器-如何将自定义对象传递给不了解restangular的 Controller ?

标签 angularjs error-handling typescript promise restangular

我被我所采用的方法所困扰,可能是因为我缺乏关于 Angular Promise VS Restangular Promise 等方面的知识。
我有一个带有 TypeScript 的 AngularJs 应用程序(尽管 typescript 在这里几乎无关紧要,同样适用于任何 javascript)。这些是球员:

  • Controller : 它被注入(inject)一个服务,通过这个服务 Controller 可以发送一个 POST 到一个 API
  • 服务 : 它包裹了restangular。这个想法是这个服务不会向 Controller 公开任何restangular功能。它将 Controller 从知道如何保存项目中抽象出来。它有一个接受对象并返回 Angular promise 的方法。
    export interface IRegistrationService {
        addRegistration(model: registration.BusinessRegistration): ng.IPromise<void>;
    }
    
  • Restangular 错误拦截器 :它处理来自 API 的状态为 400 的 Http 响应,因为它们是验证错误,并将它们转换为自定义对象。这个想法是最终 Controller 可以成功保存项目(通过服务发布)或获得验证错误(来自此拦截器)。

  • 这是我到目前为止所拥有的:

    restangular 错误拦截器
    restangularProvider.setErrorInterceptor((response: restangular.IResponse, deferred: ng.IDeferred<any>, responseHandler: any) => {
         if (response.status === 400) {
             let validationError: myTsd.IApiValidationErrors = getAsValidationError(response.data);
                // How to pass this validationError as an errorCallback to the controller?
                //deferred.notify(validationError); 
                //deferred.reject(validationError); //this stops the chain
                //return true; // if error not handled. But where to put the validationError?
                //return false; // if error handled. But where to put the validationError?
            }
        });
    

    使 Controller 不知道任何关于restangular的服务请注意,它应该返回一个 Angular Promise,而不是一个 RestAngular Promise。
    public addRegistration(model: registration.BusinessRegistration): ng.IPromise<void> {
         return this.restangular.all("registration")
                  .post<registration.BusinessRegistration>(model)
                    .then(() => {
                        console.log("Registration posted successfully");
                    }, (error: any) => {
                        //if I get the object here, how to make it available in the errorCallback of the controller caller?
                    }, (notify: any) => {
                        //if I get the object here, how to make it available in the errorCallback of the controller caller?
                    });
     }
    

    使用该服务但对restangular一无所知的 Controller
    //public static $inject = ["app.services.RegistrationService"];
    //.. controller code
    this.registrationService.addRegistration(this.model)
          .then(() => {
                console.log("model posted successfully in remote API")
           }, (error: myTsd.IApiValidationErrors) => {
                // if there was any validation error I need the object here
                console.log(error);
           });
    

    我应该如何链接所有内容?我的“唯一”要求是:
  • 创建该对象的逻辑位于 setErrorInterceptor 之类的中心位置,它应该区分 http 响应 400 或任何其他响应。如果响应既不是 2xx 也不是 400,它可以处理错误或将其传递给使用 restangular 的服务。没关系
  • 使用 restangular 的服务必须允许 Controller 成功或具有自定义验证错误对象的回调错误。它将 Controller 从其他一切中抽象出来。

  • 非常感谢!

    我不完全理解这里的文档 https://github.com/mgonto/restangular#seterrorinterceptor以及除了通知或拒绝之外,我还能做些什么。

    最佳答案

    Restangular的.setErrorInterceptor()是一种相当奇怪的野兽,据我所知,它不会做你想让它做的事情。

    它可以感知错误代码(例如您的 400)并在出现这种情况时执行操作,但除了返回 false(阻止)或返回任何其他内容(不阻止)之外没有其他能力。

  • 非阻塞 Action 允许 Promise 链走其自然的、不被拦截的过程。
  • 阻塞 Action 同时抑制了 Promise 链的错误路径和成功路径。

  • 因此想到.setErrorInterceptor()作为“选择性拦截器”,而不是“过滤器”或“捕获”,并将其与 promise.catch() 进行对比行为,由此:
  • 通过返回一些值/对象,可以将错误状态转换为成功,
  • 可以重新抛出错误,或者可以抛出一些新错误,从而将 promise 链保持在错误路径上。
  • .setErrorInterceptor() 的无能为力传播原始错误以外的任何内容似乎可以减轻它的影响,有利于命名的“捕获处理程序”(例如 getAsValidationError() 或包装 getAsValidationError() 的函数),可以包含在任何相关的地方。那应该为您提供所需的功能。

    我能预见的唯一问题是让 catch 处理程序识别“400”条件 - 可能很简单 - 需要研究。

    不要太拘泥于 Angular 的 promise 和 Restangular。它们应该互操作。

    关于angularjs - Restangular错误拦截器-如何将自定义对象传递给不了解restangular的 Controller ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35469006/

    相关文章:

    javascript - Angular UI 掩码验证

    javascript - 双向绑定(bind)无法识别 AngularJS 中的变量变化

    ruby-on-rails - RSpec示例失败,出现我预期的错误

    Angular Material - 在点击按钮时显示 mat-error

    css - 如何使 "ng-multiselect-dropdown"成为 Anguar7 中的必填字段?

    javascript - Angular ui Bootstrap ,$scope.$watch 不起作用

    javascript - 单击图像后如何创建下拉菜单? [ Bootstrap/Angular ]

    java - ADF 面对 : It's possible to Customize Error Handling without ADF BC

    c# - 解析文件中的Net Core Catch语句和其他业务逻辑

    typescript - TS2345 : type 'Construct' is not a class derived from 'Construct'