Reputation: 2751
I have an issue with requirejs and backbone. Well, I have two views (View1 and View2). I want to call View2.render() from View1 and View1.render() from View2. In general I want each view to depends to another.
My problem is that I cannot call View2.render(). I am getting the error message "cannot call method render of undefined"
If I remove the View1 dependency from View2 then it will work.
Does anyone know how can I amend the code so it could work without issues?
EDIT
View Name-->View2
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;
});
View Name --> View1
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;
});
Thanks
Upvotes: 2
Views: 1024
Reputation: 1944
First add EventBus module. This is basically Event Aggregator Pattern:
define([
'Underscore',
'Backbone'
], function(_, Backbone){
var EventBus = {
};
_.extend(EventBus, Backbone.Events);
return EventBus;
});
Next, use EventBus module for sending messages between modules. This also lets you subscribe for these events in multiple modules and helps to keep Single responsibility principle.:
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;
});
Upvotes: 4
Reputation: 20477
Circular dependencies is covered in the require.js documentation here: http://requirejs.org/docs/api.html#circular
You need to include require in your dependency list (as a param to Define function), and then use require() to call the other view, e.g.:
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;
});
Upvotes: 0