4 Stimmen

Kann nicht auf "this" im Bind-Rückruf in der Backbone.js-Anwendung zugreifen

Also hier ist mein einfaches Popover-Modul wieder. Es kann einer Ansicht zugewiesen werden, die das Popover auslöst:

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();
    }
  });

  // Erforderlich, um das Modul für die AMD-Konformität zurückzugeben.
  return Popover;
});

So setze ich das 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'));
    }
});

Ich möchte, dass die toggle-Funktion des Popovers aufgerufen wird, wenn this.$el.find('.member') angeklickt wird. Das funktioniert gut. Allerdings kann ich innerhalb der toggle-Funktion nicht auf "this" vom Popover-Objekt zugreifen, stattdessen enthält "this" das HTML seines Elternelements. Daher erhalte ich in der toggle-Funktion einen Fehler:

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

Irgendwelche Ideen, wie ich Zugriff auf das eigentliche Popover-Objekt im toggle-Callback erhalten kann?

4voto

Simon Boudrias Punkte 41491

In JavaScript erstellen Funktionen einen neuen Kontext für this. Und mit jQuery, wenn Sie Ereignisse binden, weist jQuery this dem aktuellen Element zu. Deshalb verlieren Sie den Kontext. Was können Sie also tun?

Zunächst können Sie den Wert von this manuell zuweisen:

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

Zweitens ist der beste Weg, Ereignisse im Backbone View event Objekt zu verwalten:

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

1voto

Jonathan Naguin Punkte 14066

Sie müssen die Funktion an das Backbone-Objekt binden, zum Beispiel im initialize Methode mit:

initialize: function() {
      this.visible = true;
      _.bindAll(this, 'toggle');
      this.render();
}

1voto

oooyaya Punkte 1744
 this.reference.bind('click', this.toggle, this);  // 3rd param is a context

oder

_.bindAll(this, "toggle");

...aber die erste ist besser.

Aus den BackboneJS-Dokumenten:

Binding "this" Vielleicht das häufigste JavaScript-"Gotcha" ist die Tatsache, dass beim Übergeben einer Funktion als Rückruf, ihr Wert für this verloren geht. Mit Backbone, wenn es um Ereignisse und Rückrufe geht, werden Sie oft feststellen, dass es nützlich ist, sich auf _.bind und _.bindAll von Underscore.js zu verlassen.

Beim Binden von Rückrufen an Backbone-Ereignisse können Sie sich entscheiden, ein optionales drittes Argument zu übergeben, um das this anzugeben, das verwendet wird, wenn das Rückruf später aufgerufen wird.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X