【问题标题】:how to catch angular ng-include error如何捕获角度 ng-include 错误
【发布时间】:2014-01-17 03:38:35
【问题描述】:

当我使用ng-include作为标题时,地址(文件路径)不存在时如何捕捉错误?

我在ng-view(with ng-route) 中完成了ng-include router, 有点像这样:

内容控件

var content = $route.current.params.content,
    tmplArr = content.split("_"),
    tmpl = {},
    personId=$route.current.params.personId||$scope.persons[0].id;
$scope.personId=personId;
tmpl.url = "content/";
for (var i = 0, len = tmplArr.length; i < len; i++) {
    tmpl.url += tmplArr[i] + "/";
}
tmpl.url = tmpl.url.substring(0, tmpl.url.length - 1) + ".html";
$scope.template = tmpl;

内容视图

<div ng-include="template.url" class="ng-animate"></div>

当我使用 addr 时,例如:/home/#/content/profile_asdfa, 角度只是在循环中获取资源。 因此,当哈希中没有模板文件时,我需要捕获 ng-include 错误。 有谁能够帮我 ?谢谢!

【问题讨论】:

  • 与您的问题无关,但最好不要在元素中包含 ng-animate 类。当 Angular 执行其进入/离开动画时,它会自动添加(+ 删除),因此它可能会导致稍微不可预测的行为。

标签: javascript angularjs angularjs-ng-include


【解决方案1】:

查看source for ngInclude,当模板不存在时,似乎没有直接检测404(或其他)错误的钩子或方法。您可能需要考虑添加此功能请求,因为这听起来像是一个有用的功能。

但是,现在您可以使用 http 响应拦截器来做一些事情。如果有某种方法可以判断 http 请求是否用于模板,比如它在“内容”目录中,您可以拦截错误,并对它们进行处理。例如,您可以用自定义指令替换数据,然后发出一个事件,以便控制器可以响应它。

拦截器可以这样写:

app.config(function ($httpProvider) {
    $httpProvider.interceptors.push('templateInterceptor');
});

// register the interceptor as a service
app.factory('templateInterceptor', function($q) {
  return {
    'responseError': function(rejection) {
       var isTemplate = !!rejection.config.url.match(/^content/g);
       if (isTemplate) {
         rejection.data = '<div><template-error url="\''+ (rejection.config.url) + '\'"><strong>Error from interceptor.</strong></template-error></div>';
         return rejection;
       } else {
         return $q.reject(rejection);
       }
    }
  }
});

因此,当从“内容”指令获取内容后出现错误时,它会添加一个元素 &lt;template-error&gt; 来代替模板内容。当它被编译然后链接时,它$emits 一个自定义事件templateError,父控制器可以响应$scope.$on。所以指令可以像这样编码:

app.directive('templateError', function() {
  return {
    restrict: 'E',
    scope: {
      'url': '='
    },
    link: function(scope) {
      scope.$emit('templateError', {url:scope.url});
    }
  };
});

然后在原来ngInclude的父控制器中,就可以对这个事件做出反应了:

$scope.$on('templateError', function(e, data) {
  $scope.templateError = true;
  $scope.templateErrorUrl = data.url;
})

您可以看到full working code in this Plunker。虽然我认为这有点 hacky,但如果 Angular 团队决定在错误时将 $emited 事件添加到 ngInclude 的代码中,那么删除拦截器/您的自定义元素应该很容易。

【讨论】:

  • 看来你的方案可以解决我的问题,我稍后试试。谢谢很多:)
  • 我可以假设加载 ng-view 模板时相同的解决方案可以工作吗?
  • @ruben 我不明白为什么不...你可以随时尝试看看:-)
猜你喜欢
  • 2016-08-07
  • 2015-05-10
  • 2019-06-30
  • 2016-11-24
  • 1970-01-01
  • 2014-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多