【问题标题】:Backbone/Marionette Routing for non-root page非根页面的主干/木偶路由
【发布时间】:2013-09-05 01:19:05
【问题描述】:

我们在同一个 MVC 应用程序中有多个单页应用程序。我们正在使用 Backbone/Marionette,并且路由似乎不起作用(从不触发默认的 Route 操作)。

代码:

QaApp.module("QaApp", function (Mod, App, Backbone, Marionette, $, _) {
    QaApp.Router = Marionette.AppRouter.extend(
        {
            appRoutes: {
                '' : 'subscribe',
                ':id': 'subscribe',
                '/qa/index/:id': 'subscribe'
            }
        });

    var Api = {
        subscribe: function (id) {
            //never fires
            console.log("subscribing with id = " + id);
            QaApp.Lightstreamer.Do('subscribeUpdate', {
                adapterName: 'QaAdapter',
                field: ['jsonString', 'firstData'],
                parameterValue: id,
                onUpdate: load
            });
        },
        load: function (data) {
            var question = new QaApp.Question({ id: data.id, collection: data.messages });
            var questionView = new QaApp.QuestionView(question);
            QaApp.page.show(questionView);
        }
    };

    QaApp.addInitializer(function () {
        var router = new QaApp.Router(
        {
            controller: Api
        });
        console.log(router.appRoutes);
    });
});

标准路由器似乎假设您的根 url 是 http://localhost,或者如果不是,则路由是 # 之后的任何内容(无论如何都找不到好的文档)。

所以,对于我们来说,当您登陆页面时,网址可能是:

http://localhost/qa/index/1 其中控制器为“qa”,视图为“index”,id 为 1。

我希望我的“订阅”操作在此默认网址上触发并将“id”作为参数。

我应该使用什么路线?

注意:根据this post,我已验证 Backbone.history.start() 在初始化程序运行后被调用。

另请注意:在 appRoutes 下是我尝试过的所有不同路线。我知道我只需要一个,只要我能找到合适的。

提前致谢!

更新:单步执行主干代码,“this.handlers”似乎是一个空数组,因此 url 似乎永远无法匹配。

基于更新答案的更新:传入根确实使主干认识到我在根,所以我更接近,但在下面的片段中,“片段”是“”,this.handlers 是0 长度数组,“匹配”返回 false:

loadUrl: function (fragmentOverride) {
            var fragment = this.fragment = this.getFragment(fragmentOverride);
            var matched = _.any(this.handlers, function (handler) {
                if (handler.route.test(fragment)) {
                    handler.callback(fragment);
                    return true;
                }
            });
            return matched;
        }

最终更新:处理程序为空是问题所在,结果证明是由于页面上部分加载了第二个主干.js 实例 - 所以一个实例设置了处理程序,而另一个没有设置处理程序

谢谢,大卫!

【问题讨论】:

    标签: backbone.js marionette


    【解决方案1】:

    如果您不想在 URL 中包含“#”,则需要使用 pushState 和

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

    请注意,要使其正常工作,您的 Backbone 应用程序可以生成的每个 URL 都必须存在于服务器上。换句话说,服务器必须为它可以访问的每个 URL 返回一个有效页面给您的应用程序。每个 URL 的内容不必不同(您可以发送相同的 index.html 内容,其中包含您的应用程序并让 Backbone 处理应显示的内容),但需要向客户端发送一些内容。

    根据评论编辑:

    它没有按预期运行的原因是因为您用来启动 Backbone 应用程序的任何页面默认情况下都是它的根 URL,因此不会执行任何路由。尝试在启动历史记录时设置root 属性(参见http://backbonejs.org/#History-start

    【讨论】:

    • 谢谢,大卫。我实际上尝试过,它似乎没有任何区别。我不反对在页面加载后在 url 中使用 # 。我的问题是起点“xxx/qa/index/1”与路线“qa/index/:id”不匹配,这就是我需要发生的事情。
    • 刚刚添加了一个更新——进入主干路由器,似乎“处理程序”数组总是空的,所以我想知道木偶和主干之间是否有问题(即,我没有设置它正确)。我基本上是从 Derek 的书中复制了这一点,所以不确定为什么它不起作用,但我可能遗漏了一些东西。
    • 谢谢 - 很抱歉让您感到痛苦。在您的编辑后更新。更近了,但仍然缺少一些东西。非常感谢您的意见。
    猜你喜欢
    • 1970-01-01
    • 2013-07-15
    • 2014-09-10
    • 2014-09-11
    • 1970-01-01
    • 1970-01-01
    • 2014-11-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多