BackboneJS — Проблемы с маршрутизатором — как получить чистые URL-адреса

хорошо, у меня есть

{{#each mainmenu}}
<li>
    <a href="#pages/{{this.url}}"><h2>{{this.name}}</h2></a>
</li>
{{/each}}

и в моем роутере

routes: {
    '': 'index',
    'pages/firstpage' : 'firstpage',
    'pages/secondpage' : 'secondpage',
    'pages/thirdpage' : 'thirdpage'
},
initialize: function () {
   Backbone.history.start({pushState: false});
}

и мой файл json:

{
    "name":"First page",
    "id":"1",
    "url":"firstpage"
},
{
    "name":"Second page",
    "id":"2",
    "url":"secondpage"
},
{
    "name":"Third page",
    "id":"3",
    "url":"thirdpage"
}

так, как сейчас, мой URL-адрес "#pages/secondpage" - как я могу получить URL-адрес для отображения "pages/secondpage" - я пробовал "pushState:true", который не работал... затем в моем представлении mainmenu.js Я добавил событие:

events: {
     'click a.second': 'secondpage'
},

secondpage: function() {
    var secondpageRouter = new Backbone.Router();
    var route = 'pages/secondpage';
    secondpageRouter.navigate(route, {trigger: true});
  }

но это тоже не сработало... когда я удаляю "#pages/" из привязки выше, я почти получаю URL-адрес, который мне нужен, "pages/secondpage", но он говорит: "URL не может быть найден" после нажатия на ссылку. Так что тут происходит???

Пожалуйста, помогите кому-нибудь?


person SHT    schedule 10.12.2013    source источник
comment
<a href="/pages/{{this.url}}"> в сочетании с pushState:true должно работать.   -  person mu is too short    schedule 11.12.2013
comment
к сожалению нет :-(   -  person SHT    schedule 11.12.2013
comment
Я думаю, что вы были близки с последним фрагментом кода, вам просто нужно было добавить event.preventDefault().   -  person RustyToms    schedule 11.12.2013
comment
@muistooshort для меня это не имеет смысла. Весь смысл backbone.js в том, чтобы не возвращаться на сервер для обновления страницы. Если вы не preventDefault() ссылку, она отправит get запрос на сервер. В этом примере используется preventDefault() .   -  person RustyToms    schedule 11.12.2013
comment
@RustyToms: Хм, забыл о том, что make <a>s ведут себя разумно, как хакерские шаблоны, которые я похоронил в своем приложении. Это и жизнь на стороне сервера в течение последних шести месяцев.   -  person mu is too short    schedule 11.12.2013
comment
какой браузер ты используешь? Поскольку это функция HTML5, для неподдерживающего браузера Backbone вернется к версии фрагмента.   -  person coderek    schedule 11.12.2013


Ответы (1)


Поймите, что вам нужно иметь возможность обслуживать эти URL-адреса с сервера, если это необходимо, прочитайте документацию здесь: http://backbonejs.org/#History

Затем вам нужно сделать как минимум три вещи.

Во-первых, после того, как вы определили свои маршрутизаторы, вызовите Backbone.history и убедитесь, что pushState имеет значение true:

Backbone.history.start({ pushState: true })

Во-вторых, избавьтесь от всех # в своих ссылках, например:

<a href="pages/{{this.url}}"><h2>{{this.name}}</h2></a>

В-третьих, и это важно, вам нужно перехватывать все клики по локальным ссылкам и предотвращать их поведение по умолчанию, которое будет направлять вас на новую страницу. Это легко с jQuery:

$(document).on("click", "a[href^='/']", function(event){
  event.preventDefault();
  RouterNameGoesHere.navigate($(event.target).attr("href"), {trigger: true});
});

Если вы не используете jQuery, прослушайте события щелчка по ссылке в ваших представлениях, связанные с URL-адресом в ваших обработчиках событий. Я изменил ваш код, добавив аргумент event и event.preventDefault():

events: {
  'click a.second': 'secondpage'
},

secondpage: function(event) {
  event.preventDefault();
  var secondpageRouter = new Backbone.Router();
  var route = 'pages/secondpage';
  secondpageRouter.navigate(route, {trigger: true});
}

Вот интересный пост в блоге об этой проблеме< /а>

person RustyToms    schedule 11.12.2013
comment
Самая важная часть документации: Обратите внимание, что для использования реальных URL-адресов ваш веб-сервер должен иметь возможность корректно отображать эти страницы, поэтому также требуются внутренние изменения. Например, если у вас есть маршрут /documents/100, ваш веб-сервер должен иметь возможность обслуживать эту страницу, если браузер посещает этот URL-адрес напрямую. Для полной сканируемости поисковой системы лучше всего, чтобы сервер генерировал полный HTML-код для страницы... но если это веб-приложение, просто рендеринг того же содержимого, что и для корневого URL-адреса, и заполнение остального с помощью Backbone. Представления и JavaScript работают нормально. - person RustyToms; 11.12.2013
comment
Большой! это сработало! Что я заметил, так это то, что когда я использую свой локальный хост с URL-адресом localhost/projectfolder/projectname, а затем нажимаю привязку второй страницы, он делает мой URL-адрес localhost/pages/secondpage - как сохранить папку проекта и имя проекта? - person SHT; 11.12.2013
comment
@SHT, все, что вы хотите в своем URL, должно быть в вашей ссылке. Затем вы можете каким-то образом подделать маршрут, но если это тот URL, который вам нужен, вы также должны включить его в свои маршруты. Таким образом, href="projectfolder/pages/{{this.url}}" и маршрут будет /projectfolder/pages/secondpage и т. д. - person RustyToms; 11.12.2013
comment
И пока мы на этом, нет смысла делать новый маршрутизатор каждый раз, когда вы хотите перемещаться. Сделайте маршрутизатор один раз и сохраните его как глобальную переменную. Затем вызовите глобальную переменную, когда вам понадобится маршрутизатор. Таким образом, кнопки «назад» и «вперед» будут работать. Они, вероятно, не работают для вас, как есть, верно? - person RustyToms; 11.12.2013
comment
Да, вы абсолютно правы. Где объявить эту глобальную переменную? - person SHT; 11.12.2013
comment
@SHT Вот мой код для моего приложения Backbone: window.AFB = AutoFormBot = { Models: {}, Collections: {}, Views: {}, Routers: {}, initialize: function($rootEl, forms){ console.log("AutoFormBot initialized"); AFB.formCollection = new AFB.Collections.Forms(forms); new AFB.Routers.FormRouter($rootEl); Backbone.history.start(); } }; Так что это AFB.Routers.FormRouter для меня, и я объявляю это правильно, когда запускаю свое приложение. Мне нужен только один роутер. Backbone.history.start() — это то, что заставляет работать кнопки «вперед» и «назад». - person RustyToms; 11.12.2013
comment
Не стесняйтесь принять этот ответ. Я новичок, и я мог бы использовать представителя, и я думаю, что это может помочь другим в будущем. - person RustyToms; 11.12.2013
comment
Я читал, что ответ на глубокую ссылку зависит от настройки сервера? Тогда как я должен проверить это на локальном хосте ?? (просто открытая мысль) - person SHT; 11.12.2013