show/hide div/view with backbone.js
backbone.js, jquery
Solution
If there is no parent view , then you can wire the events up between the views outside of each of the views like this.
var viewClicked = new ViewClicked();
var viewListening = new ViewListening();
viewListening.listenTo(viewClicked, "clicked:view", viewListening.respondToClick);
You don't need a parent view to do the above, even though a parent view is probably a good idea as comments suggest. In fact the method is the same regardless of whether you wire the events up in a parent view or not!
So you can do it your way by handling the event in the initialize function, but that couples one view to another. Alternatively you can do it like is demonstrated above, which prevents view coupling, but requires a parent view, some sort of closure or pollutes the global scope. Generally its better not to tightly couple views tightly as it reduces encapsulation and possible reuse, so you may consider a change to adopt the above approach in some way.
Lastly, you could use some sort of central event bus (pub sub object), which is discussed in this question. This would introduce another object, but allow you to handle the event in the intialize function of the view, but with less tight coupling (you'll couple to a global or scoped event bus, instead of a specific view).
Of course you can use an locally scoped event bus in a parent view too :)
Update
If you only have one view and the anchor is outside the view, you can use a standard jQuery click event on the anchor to call a toggle function on the view. Its important to note the use of `_.bindAll` to ensure the context of the toggle event is the view object. For example:
HTML
<a href="#" id="showView">click me</a>
<div id="myView"></div>
JAVASCRIPT
var MyView = Backbone.View.extend({
initialize: function() {
// _.bindAll binds functions called by events to the
// view (by passing it the view context as 'this'
_.bindAll(this, "toggle");
// put some content in the view
this.$el.append("Now you see me!");
},
toggle: function() {
// jQuery toggle function
this.$el.toggle();
}
});
var myView = new MyView({ el: $("#myView")});
$("#showView").click(myView.toggle);
I've provided you a working fiddle so you can see it in action.
The initial points I mentioned in regards to using a parent view or some sort of closure are still a good idea. Is there really any reason why not to?
Update 2
Doing it with a parent view, which contains child views is as follows:
HTML
<div id="parentView"></div>
JAVASCRIPT
var ShowView = Backbone.View.extend({
events: {
"click #showView": "click"
},
click: function() {
this.trigger("showView:click");
},
render: function() {
this.$el.append('<a href="#" id="showView">click me</a>');
return this;
}
});
var MyView = Backbone.View.extend({
initialize: function() {
// _.bindAll binds functions called by events to the
// view (by passing it the view context as 'this'
_.bindAll(this, "toggle");
// put some content in the view
},
render: function() {
this.$el.append('Now you see me!');
return this;
},
toggle: function() {
// jQuery toggle function
this.$el.toggle();
}
});
var ParentView = Backbone.View.extend({
initialize: function() {
this.showView = new ShowView({
id: "showView"
});
this.myView = new MyView({
id: "myView"
});
this.listenTo(this.showView, "showView:click", this.myView.toggle)
},
render: function() {
this.$el.append(this.showView.render().$el);
this.$el.append(this.myView.render().$el);
return this;
}
});
var parentView = new ParentView ({el: $("#parentView") });
parentView.render();
Here is a working fiddle demonstrating it. You may think that the approach with a parent view is overkill for the context of your question and you're probably right! However as your applications become more complicated with many views nested over many levels, you'll find that the parent view approach begins to make more sense and come into its own.
Problem
I've started playing with backbone.js and have come across an issue. I'd like to be able to show/hide a div (which is being rendered by a view) with an onclick event. The thing is that events only work for child elements and the element being clicked is a sibbling/parent of the view. I've worked around this by adding a handler in the view 'initialize' function but I don't this is the way to go. I'm also not using a 'home view', How can I get this work otherwise?