2012-10-10 77 views
2

我有一个requirejs和backbone的问题。 那么,我有两个视图(View1和View2)。我想从View1调用View2.render(),并从View2调用View1.render()。一般来说,我希望每个视图都依赖于另一个视图。RequireJs - Backbone.Views互相依赖

我的问题是我无法调用View2.render()。我收到错误消息“不能调用方法呈现未定义”

如果我从View2删除View1依赖项,那么它将工作。

有谁知道我该如何修改代码才能正常工作?

编辑

视图名称 - >视图2

define([ 
'Underscore', 
'Backbone', 
'Handlebar', 
'views/view1' 
], function (_, Backbone, Handlebars, View1) { 
var View2 = Backbone.View.extend({ 
    initialize: function() { 
     _.bindAll(this, "render"); 
    }, 
    tagName: 'div', 
    el: '#rightPanel', 
    events: { 
     'change input#createNewCategory': 'createNewItem', 
     'click #saveEdits': 'saveData', 
     'click #clearEdits': 'render' 
    }, 
    render: function() { 
     //do something here 
    }, 
    clear: function() { 
     this.$el.empty(); 
    }, 
    createNewItem: function (e) { 
     //so something here 
    }, 
    saveData: function() { 
     //This works Fine 
     View1.render(); 
    } 
}); 

return new View2; 
}); 

视图名称 - >视图1

define([ 
'Underscore', 
'Backbone', 
'Handlebar', 
'views/view2' 
], function (_, Backbone, Handlebars, View2) { 
var View1 = Backbone.View.extend({ 
    tagName: 'li', 
    el: '#categoriesList', 
    events: { 
     'click .categoryItem': 'edit' 
    }, 
    initialize: function() { 
     _.bindAll(this, "render"); 
    }, 
    edit: function (e) { 
     View2.render(); 
     //**ERROR (cannot call method render of undefined)** 
    }, 
    render: function() { 
     //do something here 
    } 
}); 

return new View1; 
}); 

感谢

+0

都是那些在require.js的URL根目录中的视图?或者使用require Path var映射它们? –

+0

我通过传递路径来映射它们。 define([model/View1],function(View1){}) – StrouMfios

+0

代码是否完整?因为它看起来很奇怪?新的Backbone.View.extend在哪里? Define之后的功能在哪里?你能用更详细的代码更新吗? –

回答

4

首先添加EventBus模块。这基本上是Event Aggregator模式:

define([ 
    'Underscore', 
    'Backbone' 
], function(_, Backbone){ 
    var EventBus = { 
    }; 
    _.extend(EventBus, Backbone.Events); 
    return EventBus; 
}); 

接下来,使用EventBus模块在模块之间发送消息。这也可以让你订阅这些事件在多个模块,并有助于保持单一责任原则。:

define([ 
'Underscore', 
'Backbone', 
'Handlebar', 
'EventBus', 
], function (_, Backbone, Handlebars, Vent) { 
var View2 = Backbone.View.extend({ 
    initialize: function() { 
     _.bindAll(this, "render"); 
     Vent.on("View1:edit", this.render, this); 
    }, 
    tagName: 'div', 
    el: '#rightPanel', 
    events: { 
     'change input#createNewCategory': 'createNewItem', 
     'click #saveEdits': 'saveData', 
     'click #clearEdits': 'render' 
    }, 
    render: function() { 
     //do something here 
    }, 
    clear: function() { 
     this.$el.empty(); 
    }, 
    createNewItem: function (e) { 
     //so something here 
    }, 
    saveData: function() { 
     Vent.trigger("View2:save"); 
    } 
}); 

return new View2; 
}); 


define([ 
'Underscore', 
'Backbone', 
'Handlebar', 
'EventBus' 
], function (_, Backbone, Handlebars, Vent) { 
var View1 = Backbone.View.extend({ 
    tagName: 'li', 
    el: '#categoriesList', 
    events: { 
     'click .categoryItem': 'edit' 
    }, 
    initialize: function() { 
     _.bindAll(this, "render"); 
     Vent.on("View2:save", this.render, this); 
    }, 
    edit: function (e) { 
     Vent.trigger("View1:edit"); 
    }, 
    render: function() { 
     //do something here 
    } 
}); 

return new View1; 
}); 
0

只循环依赖被覆盖require.js文档在这里:http://requirejs.org/docs/api.html#circular

您需要包括需要在你的依赖列表(作为一个参数去定义功能),然后使用要求()来调用其他视图,例如:

define([ 
'require' 
'Underscore', 
'Backbone', 
'Handlebar', 
'views/view1' 
], function (require, _, Backbone, Handlebars, View1) { 
var View2 = Backbone.View.extend({ 
    initialize: function() { 
     _.bindAll(this, "render"); 
    }, 
    tagName: 'div', 
    el: '#rightPanel', 
    events: { 
     'change input#createNewCategory': 'createNewItem', 
     'click #saveEdits': 'saveData', 
     'click #clearEdits': 'render' 
    }, 
    render: function() { 
     //do something here 
    }, 
    clear: function() { 
     this.$el.empty(); 
    }, 
    createNewItem: function (e) { 
     //so something here 
    }, 
    saveData: function() { 
     //This works Fine 
     require("View1").render(); 
    } 
}); 

return new View2; 
});