Cannot access "this" in bind callback in backbone.js application

So here is my simple popover module. It can be assigned to the kind that popover will call:

function(app) { var Popover = app.module(); Popover.Views.Default = Backbone.View.extend({ className: 'popover', initialize: function() { this.visible = true; this.render(); }, setReference: function(elm) { this.reference = elm; this.reference.bind('click', this.toggle); }, beforeRender: function() { this.content = this.$el.find('.popover'); }, show: function() { //this.visible = true; }, hide: function() { //this.visible = false; }, toggle: function() { this.visible ? this.hide() : this.show(); } }); // Required, return the module for AMD compliance. return Popover; }); 

This is how I installed popover:

 Main.Views.Start = Backbone.View.extend({ template: "main/start", serialize: function() { return { model: this.model }; }, initialize: function() { this.listenTo(this.model, "change", this.render); }, beforeRender: function(){ this.popover = new Popover.Views.Default(); this.insertView(this.popover); }, afterRender: function() { this.popover.setReference(this.$el.find('.member')); } }); 

I want the popover switch function to be called when this.$el.find('.member') clicked. It works great. However, inside the toggle function, I cannot access "this" from the popover object; instead, "this" contains html from its parent. Therefore, I get an error in the switch function:

 TypeError: Object [object HTMLAnchorElement] has no method 'show' 

Any ideas on how to access the popall popover object inside a toggle callback?

+4
source share
3 answers

In JavaScript functions create a new context for this . And with jQuery, when you bind events, jQuery assigns this current element. That is why you have lost context. So what can you do?

First you can manually assign this value:

 this.reference.bind('click', _.bind(this.toggle, this)); 

Secondly, the best way is to manage events in the Backbone View event object:

 Backbone.View.extend({ events: { "click element": "toggle" } // ...rest of your code... }); 
+4
source

You need to bind the function to the Backbone object, for example, in the initialize method with:

 initialize: function() { this.visible = true; _.bindAll(this, 'toggle'); this.render(); } 
+1
source
  this.reference.bind('click', this.toggle, this); // 3rd param is a context 

or

 _.bindAll(this, "toggle"); 

... but the first is better.

From BackboneJS docs:

Binding "this" Perhaps the most common JavaScript "gotcha" is the fact that when you pass a function as a callback, its value for this is lost. With Backbone, when dealing with events and callbacks, you'll often find it helpful to rely on _.bind and _.bindAll from Underscore.js.

When linking callbacks to base events, you can optionally have a third argument to specify which will be used when the callback is later called.

+1
source

Source: https://habr.com/ru/post/1488706/


All Articles