【问题标题】:BackboneJS - Subviews navigationBackboneJS - 子视图导航
【发布时间】:2014-01-20 15:45:46
【问题描述】:

我有一个非常简单的主菜单,其中包含 4 个锚点以及与它们相关的视图。无论如何,在其中一个视图上,我想添加一个带有 3 个选项卡的小子菜单,单击它们后它们会显示不同的视图。我想出了如何使用pushState:false 来做这件事,但我想要的是一个干净的 URL。现在,我的 URL 看起来像 http://localhost/myproject/#secondpage/subview1http://localhost/myproject/#secondpage/subview2 等。那么有谁知道我如何实现 http://localhost/secondpage 无论触发哪个子视图/选项卡?

我正在使用 RequireJS 和 HandlebarsJS(用于 HTML 模板)

所以现在我的代码(sn-ps)看起来像这样:

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});
},

但这没有用,这给了我找不到网址所以...

欢迎任何帮助!提前谢谢...

[更新] 好的,根据要求,这是我的(新)路由器:

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>

希望这可以带来更多的输入/建议...这真的让我发疯了,这让我考虑使用 .show() 和 .hide() jquery 方法,即使我真的不想要...

【问题讨论】:

    标签: backbone.js handlebars.js backbone-routing


    【解决方案1】:

    您所描述的是骨干路由的工作原理,您要么使用“/secondpage/sub1”并使用服务器路由,要么使用“#secondpage/sub1”并命中骨干路由。无论哪种方式,地址栏都会使用您的 URL 进行更新。

    另一种选择是在视图中使用事件,处理点击事件并相应地更新视图的模板。

    但是,如果您打算使用路由,则可以查看clickify.js。我自己还没有使用过它,虽然我已经为它添加了书签以备将来使用......听起来它可能会做你想做的事。

    【讨论】:

    • 嗯,也许我不够清楚。我宁愿避免为这样的功能使用一些脚本,这可能应该并且可以以明确的主干方式完成......
    【解决方案2】:

    尝试在您的路由器中使用它:

    Backbone.history.navigate('secondpage');
    

    所有工作完成后(获取模型,渲染视图)

    【讨论】:

    • 那还会更新网址吗?除非触发选项设置为 true,否则也不会到达路线,例如Backbone.history.navigate('secondpage', true);
    • 我认为这就是 SHT 所要求的。
    • 也许他是,也许不清楚......但他的问题以which after clicking them they show a different view. 和 Backbone.history.navigate 开始,没有触发器设置为 true,并且 pushState:false,不会(就它自己) 加载视图,只需更新 url。
    • 我同意你的观点,但是我提到的建议(尝试在你的路由器中使用它)这意味着在所有工作完成之后(模型已获取视图被渲染)他必须使用它来更新 url。
    • 我知道你现在要去哪里了;应该可以工作,虽然有点hacky。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-05
    • 2019-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-09
    相关资源
    最近更新 更多