BackboneJS — навигация по подвидам

У меня довольно простое главное меню с 4 якорями и соответствующими представлениями для них. Во всяком случае, в одном из этих представлений я хочу добавить небольшое подменю с 3 вкладками, которые после нажатия на них показывают другое представление. Я понял, как это сделать с помощью pushState:false, но мне нужен чистый URL. Прямо сейчас мой URL-адрес будет выглядеть как http://localhost/myproject/#secondpage/subview1 или http://localhost/myproject/#secondpage/subview2 и т. д. и т. д. Так кто-нибудь знает, как мне добиться http://localhost/secondpage независимо от того, какое подпредставление/вкладка запущено?

Я использую RequireJS и HandlebarsJS (для шаблонов HTML)

Итак, сейчас мой код (фрагменты) выглядит так:

Router.js

routes: {
'': 'index',
'firstpage' : 'firstpage',
'secondpage' : 'secondpage',
'secondpage/sub1' : 'sub1',
'secondpage/sub2' : 'sub2',
'secondpage/sub3' : 'sub3',
'thirdpage' : 'thirdpage'
},

Backbone.history.start({
    pushState: false
});

Мой HTML с якорями:

<ul>
<li>
    <a class="sub1" href="#secondpage/sub1">Bands</a>
</li>
<li>
    <a class="sub2" href="#secondpage/sub2">Koncert</a>
</li>
<li>
    <a class="sub3" href="#secondpage/sub3">Locations</a>
</li>   
</ul>

и мой взгляд выглядит

  define(['backbone','handlebars', 'text!templates/SubMenu.html'],

    function(Backbone,Handlebars, Template) {


        'use strict';

        var SubMenuView = Backbone.View.extend({

            template: Handlebars.compile(Template),

            initialize: function () {
                _.bindAll(this);
            },

            render: function() {
                $(this.el).html(this.template());
                return this;
            }

        });

        return SubMenuView;


    }
  );

Другое дело: нужно ли перемещать действия в представление, устанавливая события? Я как бы пробовал это, но это не сработало, так как представления определены в маршрутизаторе...

Что я пробовал, так это установить pushState:true, затем я удалил secondpage/sub1 штучки в своем маршрутизаторе, а затем в своем представлении я написал:

events: {
'click a.sub1': 'sub1',
},

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

но это не сработало, это дало мне URL не найден, так что...

Любая помощь приветствуется! Заранее спасибо...

[ОБНОВЛЕНИЕ] Итак, по запросу, вот мой (новый) маршрутизатор:

var Router = Backbone.Router.extend({

routes: {
    '': 'index',
    'firstpage' : 'firstpage',
    'secondpage' : 'secondpage',
    'thirdpage' : 'thirdpage'
},

initialize: function () {
    var self = this;

    //Views
    this.mainMenuView = new MainMenuView({el:'#mainMenu'}).render();
    this.subMenuView = new SubMenuView();

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

},

index: function () {
    var self = this;
},

firstpage: function() {
    this.firstpageView = new FirstpageView({el:'#topContent'}).render();
},

secondpage: function() {
    this.secondpageView = new SecondpageView({el:'#topContent'}).render();
    this.subMenuView = new SubMenuView({el:'#subMenu'}).render();
},

thirdpage: function() {
    var thirdpageView = new ThirdpageView({ el:'#topContent', collection:this.categoryCollection}).render();
},

sub1: function() {
    this.sub1View = new Sub1View({el:'#subContent_2'}).render();
},

sub2: function() {
    this.sub2View = new Sub2View({el:'#subContent_2'}).render();
},

sub3: function() {
    this.sub3View = new Sub3View({el:'#subContent_2'}).render();
}                       


});

return Router;
}

И мой (новый) вид выглядит так:

var SubMenuView = Backbone.View.extend({

template: Handlebars.compile(Template),

events: {
'click .sub1': 'sub1',
'click .sub2': 'sub2',
'click .sub3': 'sub3',

},

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

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

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

initialize: function () {
    _.bindAll(this);
},

render: function() {
    $(this.el).html(this.template());
    return this;
}

 });

 return SubMenuView;

И мой (новый) HTML-шаблон:

<ul>
<li>
    <a class="sub1" href="/secondpage/">Sub1</a>
</li>
<li>
    <a class="sub2" href="/secondpage/">Sub2</a>
</li>
<li>
    <a class="sub3" href="/secondpage/">Sub3</a>
</li>   
</ul>

Надеюсь, это может способствовать большему количеству входных данных/предложений... Это действительно сводит меня с ума, что заставляет меня подумать об использовании метода jquery .show() и .hide(), даже если я действительно не хочу...


person SHT    schedule 20.01.2014    source источник


Ответы (2)


Вы описываете, как работает магистральная маршрутизация: либо вы используете «/secondpage/sub1» и используете серверные маршруты, либо используете «#secondpage/sub1» и выбираете магистральную маршрутизацию. В любом случае адресная строка будет обновляться с вашим URL.

Одним из альтернативных вариантов является использование событий внутри представления, обработка события щелчка и соответствующее обновление шаблона представления.

Однако, если вы намерены использовать маршруты, обратите внимание на clickify.js. Я еще не использовал его сам, хотя я добавил его в закладки для возможного использования в будущем ... похоже, что он может делать то, что вы хотите.

person Jonathan Miles    schedule 20.01.2014
comment
хм, может быть, я был недостаточно ясен. Я бы предпочел избегать использования какого-либо скрипта для такой функции, которая, вероятно, должна и может быть сделана четким магистральным способом... - person SHT; 20.01.2014

попробуйте использовать это в своем маршрутизаторе:

Backbone.history.navigate('secondpage');

после того, как вся работа сделана (модели загружены, представления визуализированы)

person Rida BENHAMMANE    schedule 20.01.2014
comment
Это по-прежнему будет обновлять URL-адрес? Также не будут затронуты маршруты, если для параметра триггера не установлено значение true, например. Backbone.history.navigate('вторая страница', правда); - person Jonathan Miles; 20.01.2014
comment
Я думаю, это то, о чем просит SHT. - person Rida BENHAMMANE; 20.01.2014
comment
Может быть, это так, возможно, это неясно ... но его вопрос начинается с which after clicking them they show a different view. и Backbone.history.navigate без триггера, установленного в true, и pushState: false, не будет (сам по себе) загружать представления, просто обновите URL. - person Jonathan Miles; 20.01.2014
comment
Я согласен с вами, но мое предложение, как я уже упоминал (попробуйте использовать это в своем маршрутизаторе), означает, что после того, как вся работа сделана (модели получены, представления отрисованы), он должен использовать это. просто обновить URL. - person Rida BENHAMMANE; 20.01.2014
comment
Я вижу, куда ты идешь сейчас; должно работать, хотя и немного хакерски. - person Jonathan Miles; 20.01.2014