当ng-include用作标题时,如果地址(文件路径)不存在,如何捕获错误?
ng-include
我完成了一个的ng-include router内部ng-view(with ng-route),有点像这样:
ng-include router
ng-view(with ng-route)
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;
ContentView :
<div ng-include="template.url" class="ng-animate"></div>
当我使用addr不存在:/ home /#/ content / profile_asdfa时,角度只是在循环中获取资源。因此,当哈希中没有模板文件时,我需要捕获ng-include错误。有谁能够帮我 ?谢谢!
在源代码中查找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); } } } });
因此,当从“内容”指令中获取内容后出现错误时,它将添加一个元素<template- error>来代替模板内容。编译然后链接该$emit控件时,它是一个自定义事件,templateError父控制器可以通过响应此事件$scope.$on。因此,该指令可以像下面这样编码:
<template- error>
$emit
templateError
$scope.$on
app.directive('templateError', function() { return { restrict: 'E', scope: { 'url': '=' }, link: function(scope) { scope.$emit('templateError', {url:scope.url}); } }; });
然后在原始的父控制器中ngInclude,您可以对此事件做出反应:
ngInclude
$scope.$on('templateError', function(e, data) { $scope.templateError = true; $scope.templateErrorUrl = data.url; })
您可以在此Plunker中看到完整的工作代码。尽管我认为这有点不客气,但是如果Angular团队决定将$emited事件添加到ngIncludeon错误代码中,那么只需删除拦截器/自定义元素就应该很容易。