我在我的应用程序中使用angularjs,一切正常但在加载模板之前我只想检查它实际存在于给定路径上。
这是我的代码:
.when("/:page", angularAMD.route({
templateUrl: function (rp) {
return 'public/templates/' + rp.page.replace('.html', '') + '.php'; },
resolve: {
load: ['$q', '$rootScope', '$location',
function ($q, $rootScope, $location) {
var path = $location.path();
//console.log(path);
var parsePath = path.split("/");
var controllerName = parsePath[1];
controllerName = controllerName.replace('.html', '').replace('_', '');
var loadController = "public/js/controllers/" +
controllerName + "Controller.js";
var deferred = $q.defer();
require([loadController], function () {
$rootScope.$apply(function () {
deferred.resolve();
});
});
return deferred.promise;
}]
}
}))
我希望在执行此操作之前return 'public/templates/' + rp.page.replace('.html', '') + '.php'; }
必须检查此文件是否存在,否则我想重定向到404页。
现在发生的是,当我访问一些无效链接时,我没有获得404状态,而是加载主index.html文件,因此,它开始在无限循环中运行相同的代码,在最后一个浏览器挂起。
感谢您的帮助,谢谢。
答案 0 :(得分:1)
在ngRoute中,您需要在config
块中配置路由,并且在配置块内部不能使用工厂和服务,因此您可以使用一个简单的技巧来检查模板是否存在,如果没有返回您的404页面。
var checkTplUrl = function(url) {
var http = new XMLHttpRequest();
http.open('HEAD', url, false);
http.send();
return (http.status !== 404) ? url : './404.html';
};
.when("/:page", angularAMD.route({
templateUrl: function (rp) {
return checkTplUrl('public/templates/' + rp.page.replace('.html', '') + '.php'); },
resolve: {
load: ['$q', '$rootScope', '$location',
function ($q, $rootScope, $location) {
var path = $location.path();
//console.log(path);
var parsePath = path.split("/");
var controllerName = parsePath[1];
controllerName = controllerName.replace('.html', '').replace('_', '');
var loadController = "public/js/controllers/" +
controllerName + "Controller.js";
var deferred = $q.defer();
require([loadController], function () {
$rootScope.$apply(function () {
deferred.resolve();
});
});
return deferred.promise;
}]
}
}))
答案 1 :(得分:0)
(or $scope.$on)
$rootScope.$on("$routeChangeError", function(event, current, previous, eventObj) {
//redirect your user to custom 404 page;
});
答案 2 :(得分:0)
你应该在任何非平凡的angular.js应用程序中做一些事情,可能对他们来说最好的地方是你定义主模块,然后是配置块然后是运行块。
如果没有处理和记录那些$ routeChange事件(或者使用ui-router $ stateChange事件时),你基本上是盲目的,会错过错误,重复路由更改和其他讨厌的事情......
这里使用ui-router时的示例,如果使用角度基本路由,则使用角度路由器的respecitve事件。
angular.module('yourMainModuleName', ['your dependencies'])
.config(['$someProvider', function(someProvider) {
// do setup all your global providers here
// e.g. $http, restangular, ui-router, angular-translate....
} ])
.run(['$rootScope', '$state', '$stateParams',
function($rootScope, $state, $stateParams ) {
// put ui-router $state on $rootScope, so we have access to it in all $scopes
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
$rootScope.$on("$stateChangeStart", function (event, toState, toParams, fromState, fromParams) {
// always see what happens in your app!
console.debug('stateChangeStart from: ' + (fromState && fromState.name) + ' to: ' + toState.name);
// handle auth here as well, check whether user is allowed to go to this state, abort if not
...
});
$rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState, fromParams) {
// see what happens in your app!
console.debug('stateChangeSuccess from: ' + (fromState && fromState.name) + ' to: ' + toState.name);
});
// log stateChangeErrors
$rootScope.$on("$stateChangeError", function (event, toState, toParams, fromState, fromParams, error) {
console.log('Error on StateChange from: "' + (fromState && fromState.name) + '" to: "'+ toState.name + '", err:' + error.message + ", code: " + error.status);
$state.go('home');
});
}]);
答案 3 :(得分:0)
创建一个服务,检查文件是否存在并返回一个承诺!
$http.head("template2check").then(function () {
return true;
}, function () {
return false;
});
在控制器中使用服务:
<service>.<service method>.then(function (found) {
if (found) {......
});