Я использую 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'; }
return 'public/templates/' + rp.page.replace('.html', '') + '.php'; }
он должен проверить, существует ли этот файл, в противном случае я хочу перенаправить на страницу 404.
что происходит, когда я посещаю какую-то недействительную ссылку, я не получаю статус 404, вместо этого загружает основной файл index.html, и по этой причине он запускает тот же код в бесконечном цикле, наконец, зависает браузер.
Цените свою помощь, спасибо.
В 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
(or $scope.$on) $rootScope.$on("$routeChangeError", function(event, current, previous, eventObj) { //redirect your user to custom 404 page; });
Есть несколько вещей, которые вы должны сделать только в любом нетривиальном приложении angular.js, вероятно, лучшее место для них прямо там, где вы определяете свой главный модуль, затем блок конфигурации, а затем блок запуска.
Без обработки и регистрации этих событий $ routeChange (например, при использовании ui-router $ stateChange Events) вы в основном слепы и пропустите ошибки и дублируете изменения маршрута и другие неприятные вещи …
Здесь пример использования ui-router, если используется угловая базовая маршрутизация, использует события respecitve для углового маршрутизатора.
angular.module('yourMainModuleName', ['your dependencies']) .config(['$someProvider', function(someProvider) { // do setup all your global providers here // eg $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'); }); }]);
Создайте службу, которая проверяет наличие файла и возвращает обещание!
$http.head("template2check").then(function () { return true; }, function () { return false; });
В контроллере используйте службу:
<service>.<service method>.then(function (found) { if (found) {...... });