使用Backbone.js路由器浏览使用require.js模块化的视图

MrG*_*igg 35 requirejs backbone.js

我正在将我的观点和路由器分成带有require的单独文件.然后我有一个main.js文件来实例化路由器,并且还渲染我的默认视图.

我的路由器有视图('View /:id')和edit('Edit /:id')作为路由.在main.js中,当我实例化路由器时,我可以硬编码router.navigate('View/1',true)并且导航工作正常.在我的视图文件中,当我点击编辑链接时,我想调用router.navigate('View /'+ id,true),但我不知道该怎么做.

我成功调用了Backbone.history.navigate('View /'+ id,true),但我觉得我不应该依赖于全局Backbone对象.

我尝试传递({router:appRouter})到我的视图,所以我可以使用this.options.router.navigate(),但这对我不起作用.

如果你很好奇,我的应用程序中有一堆代码:

路由器:

define(['./View', './Edit'], function (View, Edit) {
    return Backbone.Router.extend({
        routes: {
            'View/:id': 'view',
            'Edit/:id': 'edit'
        },

        view: function (id) {
            var model = this.collection.get(id);
            var view = new View({ model: model });
            view.render();
        },

        edit: function (id) {
            var model = this.collection.get(id);
            var edit = new Edit({ model: model });
            edit.render();
        }
    });
});
Run Code Online (Sandbox Code Playgroud)

视图:

define(function () {
    return Backbone.View.extend({
        template: Handlebars.compile($('#template').html()),

        events: {
            'click .edit': 'edit'
        },

        render: function () {
            //Create and insert the cover letter view
            $(this.el).html(this.template(this.model.toJSON()));
            $('#View').html(this.el);

            return this;
        },

        edit: function () {
            Backbone.history.navigate('Edit/' + this.model.id, true); 
        },
    });
});
Run Code Online (Sandbox Code Playgroud)

Hor*_*aan 32

如果其他人像我一样正在寻找这个问题的解决方案,我会发布我最终做的事情.如果您正在使用样板backbone.js,那么您将拥有一个initialize()函数router.js.我将我的initialize()功能修改为如下所示:

initialize = function () {
  var app_router;
  app_router = new AppRouter();

  // Extend the View class to include a navigation method goTo
  Backbone.View.goTo = function (loc) {
    app_router.navigate(loc, true);
  };

  Backbone.history.start();
};
Run Code Online (Sandbox Code Playgroud)

由于backbone.js的特殊继承风格,这允许我MyView.goTo(location);从我的任何视图中调用.

  • 我不得不使用`Backbone.View.prototype.goTo =` (9认同)

nra*_*itz 20

与几乎任何Backbone问题一样,有很多方法可以解决这个问题.我在当前项目中处理它的方法是将所有内容放在全局自定义命名空间中,并使用它来传递必要的引用:

var MyNamespace = {};

MyNamespace.init = function() {
    MyNamespace.appView = new MyAppView();
    MyNamespace.router = new MyRouter();
    // etc
}
Run Code Online (Sandbox Code Playgroud)

然后可以MyNamespace.router根据需要查看视图.但看起来这不起作用/不鼓励require.js,所以这里有一些其他的选择:

  • 不要显式调用路由器 - 而是更改路由器侦听的全局状态对象.这实际上就是我在当前项目中的工作方式 - 请参阅此响应以获取更多详细信息.

  • 将路由器连接到您经常调用的顶级视图AppView,使其可以全局访问,并使用AppView.router.navigate().

  • 创建另一个提供内部navigate调用的实用程序函数的模块Backbone.history.navigate().这与你正在做的事情没什么不同,但它会使它更加模块化,让你不能一直使用全局参考.这也允许您更改内部实现.


kre*_*eek 8

你可以用window.location.hash的老式方式做到这一点:)

window.location.hash = "Edit/1"
Run Code Online (Sandbox Code Playgroud)

如果您不需要显式路由,这是另一种解决方案.当应用程序启动时,创建一个扩展Backbone Events的对象

window.EventDispatcher = _.extend({}, Backbone.Events);
Run Code Online (Sandbox Code Playgroud)

然后在你的应用程序的任何地方,你可以听取事件

EventDispatcher.bind("mymodel:edit", this.editHandler, this);
Run Code Online (Sandbox Code Playgroud)

并且从任何地方发送活动,data下面是您想要发送的任何参数

EventDispatcher.trigger("mymodel:edit", data);
Run Code Online (Sandbox Code Playgroud)


小智 5

对我来说,goTo功能的解决方案稍作改动

 Backbone.View.prototype.goTo = function (loc) {
      appRouter.navigate(loc, true);
    };
Run Code Online (Sandbox Code Playgroud)