Ember Router - Как обращаться с маршрутами 404 (не найдено)? - программирование
Подтвердить что ты не робот

Ember Router - Как обращаться с маршрутами 404 (не найдено)?

Я пытаюсь выяснить, как обрабатывать недопустимые маршруты в моем приложении, используя Ember.Router.

В настоящее время, если я вводим неверный маршрут, например. myapp.com/#FooBarDoesntExist, он перенаправляется на маршрут индекса ('/'). Мне бы хотелось, если бы я мог определить состояние notFound или 404, в котором он будет маршрутизироваться, чтобы я мог сообщить пользователю, что произошло. В отличие от них, сбрасываемых на домашней странице.

4b9b3361

Ответ 1

Ember.Router в своей текущей версии не предоставляет средств для обработки неизвестных маршрутов. Время взломать!

Решение 1 - Быстрая и грязная

Идея здесь заключается в следующем. У нас есть метод Ember.Router.route(path), который вызывается с запрошенным (потенциально неизвестным) путем. После вызова этого метода путь к маршрутизатору гарантированно будет известен. Итак, если мы сравниваем запрошенный путь и фактический путь, и они отличаются - тогда запрошенный путь недействителен, и мы можем перенаправить пользователя на страницу 404.

  App.Router = Ember.Router.extend({

    route: function(path) {
      this._super(path);
      var actualPath = this.get("currentState").absoluteRoute(this);
      if (path !== actualPath) {
        this.transitionTo("404page");
      }
    }
  });

Это решение довольно дорого. Например, если текущее состояние "/a/b/c", и пользователь хочет перейти к "/b/d/e/unknown", маршрутизатор будет покорно вводить известные состояния "b", "d" и "e", и только тогда мы отбросим путь как неизвестный. Было бы неплохо, если бы мы могли сказать это до начала фактической маршрутизации.

Решение 2 - Скрипты с частными методами

Здесь мы проверяем правильность данного пути и только тогда говорим маршрутизатору:

App.Router = Ember.Router.extend({

checkPath: function (path) {
  path = path.replace(this.get('rootURL'), '').replace(/^(?=[^\/])/, "/"); 
  var resolvedStates = this.get("states.root").resolvePath(this, path);
  var lastState = resolvedStates.get("lastObject");
  return lastState.match.remaining == "";
},

route: function(path) {
  if (this.checkPath(path)) {
    this._super(path);
  } else {
    this.transitionTo("404page");
  }
}
});

Это решение также имеет свой недостаток - он использует метод resolvePath, который помечен как закрытый. Тем не менее, я бы использовал это решение, так как оно более эффективно, чем первое.

Ответ 2

Хорошим способом решения этой проблемы является объявление маршрута, который отображает все возможные URL-адреса в дополнение к вашим маршрутам. Здесь вы можете привести пример: http://jsfiddle.net/mbreton/r3C9c/

var App = Ember.Application.create();

App.Router.map(function(){
    this.route('detail', {path: "detail"});
    this.route('missing', { path: "/*path" });
});


App.MissingRoute = Em.Route.extend({
    redirect: function () {
        Em.debug('404 :: redirection to index');
        this.transitionTo("index");
    }
});

App.ApplicationView = Em.View.extend({
    didInsertElement:function(){
        $('#missingLink').on('click', function (e){
            window.location.hash = "#/pepepepepep";
            return false;      
        });
    }
});

В этом примере все неизвестные URL-адреса перенаправляются на маршрут индекса.

Ответ 3

Рекомендуемым способом сделать это в Ember 1.13 является создание маршрута catch-all:

Router.map(function () {
  this.route('home');
  this.route('login');
  this.route('404', { path: '/*path' });  // capture route in path
});

Затем поместите свой шаблон 404 в 404.hbs.