1

除了合理的后端错误处理外,设法用 AngularJS 重写了我的项目。

我只希望有一种通用的方法来捕获 Ajax 错误响应并相应地修改范围。

在 JQuery 中,我会执行以下操作:

  1. 在 Ajax 设置上设置一个元素(我们称之为 ajaxRoot)
  2. 我会确保后端在标题“显示消息”上发送错误,其中每个键与 ajaxRoot 下的元素名称匹配。例如

    <div id="myAjaxSection">
        <span class="view-port">
              <input name="username"/>
        </span>
    </div>
    
    $.ajax({
        ajaxRoot : $("#myAjaxSection"), 
        ... 
     });
    
  3. 用于ajaxError捕获所有 ajax 错误,看起来像

    if ( ajaxSettings.ajaxRoot && jqXHR.getResponseHeader("display-messages")){
        var msgs = JSON.parse( jqXHR.getResponseHeader("display-message"));
        var $ajaxRoot = ajaxSettings.ajaxRoot;
        var k;
        for ( k in msgs ){
            $ajaxRoot.find("[name=" + k + "]" ).closest(".view-port" ).addClass("error").popover({content: msgs[k]});
        }
    }
    

假设我决定的约定,这将很容易处理任何页面上的所有错误。

现在我正在尝试使用 AngularJS 达到类似的效果。这是我到目前为止尝试过的

  1. http拦截器-但我无法访问范围。
  2. http 拦截器 + 发布/订阅事件 - 需要在每个控制器中重复代码。
  3. $http 调用上的错误处理程序 - 再次导致代码重复。

目前我被卡住了。我需要有关如何进行的指导?

编辑

我讨厌回答我自己的问题。

我现在有一个丑陋但合理的解决方案。将不胜感激有关此主题的更多答案。

4

1 回答 1

2

我现在丑陋但合理的解决方案如下:

即使拦截器无法访问“$scope”——它们也可以访问“$rootScope”。

注意- 当我调试拦截器并尝试评估“$rootScope”时,我得到一个“没有这样的引用”错误......这很奇怪。一旦我使用“console.log”打印它,它就运行良好。

在我的应用程序配置下,我会做

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

然后我定义我的拦截器如下

MyApp.factory( 'myInterceptor', function ( $rootScope, $q, $window )
{
    function success( response )
    {
        $rootScope.formErrors = {};
        return response;
    }

    function error( response )
    {
        var status = response.status;
        if ( status == 401 ) {
            window.location = "/";
            return;
        }

        var hdrs = response.headers();
        if ( hdrs["display-message"]){
            var displayMessages = JSON.parse(hdrs["display-message"]);
            if ( displayMessages["formErrors"]){
                $rootScope.formErrors = displayMessages["formErrors"];
            }
        }
        console.log(["hdrs",hdrs]);
        // otherwise
        return $q.reject( response );
    }

    return function ( promise )
    {
        return promise.then( success, error );
    };
} );

现在剩下的就是像这样从模板中引用 rootScope.formErrors

<div id="myAjaxSection">
    <span class="view-port" ng-class="{'error':formErrors['username'] != null}">
          <input name="username"/>
    </span>
</div>

其中 - 感谢模板在没有太多代码重复的情况下是可行的。

<div id="myAjaxSection">
    <span class="view-port" ng-class="{'error':formErrors['@name'] != null}">
          <input name="@name"/>
    </span>
</div>

现在剩下的就是解决如何实现“popover” - 我确信某处存在某些东西。

我讨厌这个解决方案..感觉不对..如果有人有更好的建议 - 请做。

于 2013-04-22T11:20:49.597 回答