问题描述
当我使用ng-include
作为标题时,如果地址(文件路径)不存在,我如何捕捉错误?
When I use ng-include
as a title, how do I catch the error when the address (file path) does not exist?
我在 ng-view(with ng-route)
中完成了一个 ng-include router
,有点像这样:
I finished a ng-include router
inside a ng-view(with ng-route)
,It's a little bit like this:
ContentCtrl:
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 错误.有谁能够帮助我 ?谢谢!
when I use the addr is not exist like:/home/#/content/profile_asdfa,the angular just fetch the resource in a loop.So I need to catch the ng-include error,when there is no template file in the hash.Can anybody Help me ? Thx!
推荐答案
在 ngInclude 的来源,当模板不存在时,似乎没有钩子或方法可以直接检测 404(或其他)错误.您可能需要考虑添加此功能的功能请求,因为这听起来像是一个有用的功能.
Looking in the source for ngInclude, there seems to be no hook or way to detect directly a 404 (or other) error when the template doesn't exist. You might want to consider a feature request to add this, as it sounds like a useful feature.
但是,现在您可以使用 http 响应拦截器做一些事情.如果有某种方法可以判断 http 请求是否用于模板,比如它在内容"目录中,您可以拦截错误,并对其进行处理.例如,您可以使用自定义指令替换数据,然后发出一个事件,以便控制器可以对其做出响应.
However, right now you could do something with a http response interceptor. If there is some way to tell if a http reguest is for a template, say it is in the 'content' directory, you can intercept errors, and do something with them. For example you could replace the data with a custom directive, that then emits an event so controller(s) could respond to it.
拦截器可以这样写:
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);
}
}
}
});
因此,当从 'content' 指令获取某些内容后出现错误时,它会添加一个元素 来代替模板内容.当它被编译然后链接时,它
$emit
一个自定义事件,templateError
,父控制器可以响应,通过$scope.$on
.所以指令可以像这样编码:
So when there is an error after fetching something from the 'content' directive, it adds an element <template-error>
in place of the template content. When this is compiled and then linked, it $emit
s a custom event, templateError
, which parent controllers can respond to, by $scope.$on
. So the directive can be code up like:
app.directive('templateError', function() {
return {
restrict: 'E',
scope: {
'url': '='
},
link: function(scope) {
scope.$emit('templateError', {url:scope.url});
}
};
});
然后在原来的ngInclude
的父控制器中,可以对这个事件做出反应:
And then in the parent controller of the original ngInclude
, you can react to this event:
$scope.$on('templateError', function(e, data) {
$scope.templateError = true;
$scope.templateErrorUrl = data.url;
})
您可以在此 Plunker 中查看完整的工作代码.虽然我认为这有点 hacky,但如果 Angular 团队决定在出错时将 $emit
ed 事件添加到 ngInclude
的代码中,那么删除它应该很容易拦截器/您的自定义元素.
You can see the full working code in this Plunker. Although I think this is slightly hacky, if the Angular team decide to add an $emit
ed event to the code of ngInclude
on error, then it should be easy to just remove the interceptor / your custom element.
这篇关于如何捕捉角度 ng-include 错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!