I'm new in backbone.js. And I see that in Backbone.js, the events binding :
var PersonView = Backbone.View.extend({
....
events : {
"click button.btnSay" : "saySomething"
},
saySomething : function(){
....
}
...
});
...doesn't need the button.btnSay to be existed in the time of calling, that's so similar to "delegate" in Jquery.
And now, the problem is, we can change any button in our html page to .btnSay (by Firebug, etc.). And they eventualy get the listeners. How can we prevent this?
Under the hood, Backbone uses jQuery's "delegate" to wire up the events. So it's not that this is "like" jQuery, it is jQuery doing it for us.
To prevent scoping problems and ensure that our View events are only working with the HTML/DOM elements that we want, all events
declarations are scoped to the View's el
.
When a Backbone view is instantiated, an el
attribute is either generated for you, or assigned by you. This gives you the opportunity to either attach your view to an existing chunk of the DOM or to create a new chunk of HTML that can be attached to the DOM.
Here's how you can attach to the existing DOM:
MyView = Backbone.View.extend({
// ...
});
var existingDomEl = $("#someElement");
new MyView({
el: existingDomEl
});
By specifying the el
when we instantiate the view, or by specifying it directly in our view definition, we use an existing element.
If we omit the el
from the constructor options and from the view definition, Backbone will generate an el
for us. By default it will generate a div in el
when the view is instantiated.
Once a View has it's el
, whether through generation or assignment, the view's event declarations are delegated via jQuery, scoped to the view's el
.
let's say you have the following html:
<div id="foo">
<button class="btnSay">Say!</button>
</div>
<div id="bare">
<button class="btnSay">Say, Part 2!</button>
</div>
with your example View, we could assign a view to either the foo
or the bar
element, and only the button within that element would get the click event.
var PersonView = Backbone.View.extend({
....
events : {
"click button.btnSay" : "saySomething"
},
saySomething : function(){
....
}
...
});
new PersonView({
el: $("#foo")
});
Now when you click the button in the foo
div, you'll get the saySomething
callback fired. But because the events for PersonView were scoped within the el
for that instance of PersonView, clicking the button within bar
will never fire the callback.
It isn't similar to delegate
it does use delegate
(unless the event doesn't have a selector). The event binding in Backbone looks like this:
if (selector === '') {
$(this.el).bind(eventName, method);
} else {
$(this.el).delegate(selector, eventName, method);
}
So it uses delegate
on the view's element. That at least limits the events to elements within the view.
You can't stop people from messing around with your elements and events in a debugger. They can change the HTML, the CSS, and even edit your JavaScript so you can't stop them from causing trouble on your page. You can stop them from making a mess on your server though, just don't trust anything that Backbone sends to your server and validate everything the same way you would validate anything else that comes in from the outside world.
Basically, don't waste your time worrying about someone smashing their own face with a brick by messing with your HTML/events/JavaScript. Let them hurt themselves all they want. But do protect your server by not trusting anything from the outside world (and your servers shouldn't even trust themselves any more than they have to).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With