Angularjs, как проверить, существует ли файл шаблона
Я использую 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, и по этой причине он запускает тот же код в бесконечном цикле, в последнем браузере висит.
Цените свою помощь, спасибо.
Ответы
Ответ 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;
}]
}
}))
Рабочий пример: https://plnkr.co/edit/1UjlFgT7dazMZOrAhZzY?p=info
Ответ 2
(or $scope.$on)
$rootScope.$on("$routeChangeError", function(event, current, previous, eventObj) {
//redirect your user to custom 404 page;
});
Ответ 3
Есть несколько вещей, которые вы должны сделать только в любом нетривиальном приложении angular.js, вероятно, лучшее место для них - это то место, где вы определяете свой основной модуль, затем блок конфигурации, а затем блок выполнения.
Без обработки и регистрации этих событий $routeChange (например, при использовании ui-router $stateChange Events) вы в основном слепы и пропустите ошибки и дублируете изменения маршрута и другие неприятные вещи...
Здесь пример использования ui-router при использовании базовой маршрутизации angular использует события respecitve маршрутизатора angular.
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');
});
}]);
Ответ 4
Создайте службу, которая проверяет наличие файла и возвращает обещание!
$http.head("template2check").then(function () {
return true;
}, function () {
return false;
});
В контроллере используйте службу:
<service>.<service method>.then(function (found) {
if (found) {......
});