0

在这个简单的 Require/Backbone 应用程序中

https://github.com/thisishardcoded/require-prob

为什么 app.js 可以看到 Router 而 TestView.js 没有?

这是 app.js 的第一行

define(['router'],function (Router) {

这是 TestView.js 的第一行

define(['backbone','router'],function(Backbone,Router){

查看 repo 以获取完整的详细信息,如果您愿意,请下载、运行并检查控制台日志

谢谢!吉姆

更多:好的,答案是 - 因为它的加载顺序,即使改变了我也有一个循环依赖不是吗?TestView需要Router,Router需要TestView。

在这种情况下,解决方案可能是

var r=require('router);
r.navigate or whatever

但是,Router 不能在任何地方直接访问,这似乎是一种耻辱,而且上述方法是好的做法吗?

4

4 回答 4

5

当然它是由于循环依赖而发生的。要解决它,您可以将路由器传递给视图的构造函数并从视图的模块中删除路由器依赖项,或者在视图中使用 require('router') 。

第一个选项,router.js:

app_router.on('route:test', function () {
    var testView = new TestView({router: app_router});
    testView.render();
})

第一个选项,view.js:

define(['backbone'], function(Backbone){

    var TestView=Backbone.View.extend({
        el: '#test',
        initialize: function() {
            // get router from constructior options
            this.router = this.options.router
        },
        render: function(){
            this.$el.html('<p>Foo!</p>');
            console.log("TestView.js does not find 'Router',", this.router);
        }
    });

    return TestView;

});

第二个选项,view.js:

define(['backbone','router'], function(Backbone, router){

    // at this point router module is not loaded yet so router is undefined

    var TestView=Backbone.View.extend({
        el: '#test',
        initialize: function() {
            // at this point router module is loaded and you may access it with require call
            this.router = require('router');
        },
        render: function(){
            this.$el.html('<p>Foo!</p>');
            console.log("TestView.js does not find 'Router',", this.router);
        }
    });

    return TestView;

});

此处还描述了第二个选项:http ://requirejs.org/docs/api.html#circular

于 2013-05-01T07:20:19.600 回答
0

您可以使用 availableBackbone.history.navigate更轻松地实现您的目标,因为Router.navigate它是一个简单的包装器。考虑Backbone 源代码的这一部分

navigate: function(fragment, options) {
  Backbone.history.navigate(fragment, options);
  return this;
},
于 2013-12-01T10:40:38.113 回答
0

您应该在包含 RequireJS 配置的文件中定义baseUrl属性。main.js这样,应用程序中的所有模块路径都将相对于baseUrl.

看:

http://requirejs.org/docs/api.html#jsfiles
http://requirejs.org/docs/api.html#config-baseUrl

于 2013-04-30T23:41:36.997 回答
0

我下载并检查了您的代码。以下可能是问题:

  1. require.js仅适用于AMDs. 由于骨干不再支持AMD. 您将需要使用AMD已启用的Backbone. 你可以在这里得到

  2. TestView 是您路由器中的依赖项。所以它在路由器加载之前加载。

您可能想要改进编码模式。这是我的建议:

应用程序.js

define([

'backbone', 'router', ], function(Backbone, MainRouter){ 'use strict';

var AppView = Backbone.View.extend({

    initialize: function(){

        App.router = new MainRouter();
        Backbone.history.start();
    }
});

return AppView;
});

路由器.js

define([
  'backbone',
  'view/TestView'
], function(Backbone, TestView){
    var Main = Backbone.Router.extend({
        routes: {
            'test': 'test'
        },

        test: function(){
            new TestView({
                // pass model or collection to the view
                // model: new TestModel // remember to require
            });
        }

    });

    return Main;
});

编辑 监听事件:

// in main.js
var window.Vent = {};

_.extend(window.Vent, Backbone.Events);

// now in any view you can trigger a event
$('something').on('click', function(){
    window.Vent.trigger('somethinghappened', this); 
    // this is reference to current object
});

// now in other view you can do
window.Vent.on('somethinghappened', this.run, this); 
// this in the end is the reference we passed when event was triggered

run: function(obj){
    //this function will run when the event is triggered
    // obj is the object who triggered the event
}

PS:为什么要在view中使用router??我已经构建了很多主干应用程序。从来不需要这样做。

于 2013-05-01T09:44:44.810 回答