[js/dojo] Membervariable in Callbackmethode nicht mehr verfügbar (?)

Chosi

Mitglied
Hi zusammen,

ich habe gerade ein kleines Problem mit einer Methode, welche als Callback für einen dojo.datastore dient. Immer, wenn die Methode druch den datastore aufgerufen wird, schlägt der Zugriff auf die Attribute des Objektes fehl (ich bekomme undefined). Rufe ich die Methode ganz normal auf, gibt es keine Probleme.

Ein Beispiel:
Code:
[...]

open: function()
  {
    this.gotItem();  // gibt den inhalt von this._test aus
    this._datastore.fetchItemByIdentity(
    {
      identity: 'Kannen',
      onItem: cat_browser.gotItem  // gibt für this._test undefined aus
    });
  },

  gotItem: function(item)
  {
    window.alert('gotItem: ' + this._test);
  },

[...]

Hat jemand eine Idee, woran das liegen könnte?
 
Moin,

hast du mal bitte etwas mehr Code von dem, was du da versuchst.
Es wäre recht interessant zu wissen, wem du da dieses Attribut eigentlich zuweist.
 
Hi,

hier mal das - fast - komplette Objekt. Das _test Attribut habe ich eigentlich nur zum ausprobieren eingefügt. Eigentlich will ich in gotItem() natürlich auf _datastore zugreifen, was aber auch nicht funktioniert (undefined). Irgendwie scheint er innerhalb von gotItem() - sofern als Callback vom dojo.datastore aufgerufen - keinerlei Member des Objektes mehr zu kennen. :-/

Code:
dojo.declare('fooweeh.cat_browser', null, 
{
  _elementId: null,
  _ulElement: null,
  _datastore: null,
  _test: null,

  constructor: function(argElementId)
  { 
    this._elementId = argElementId;
    
    // retrieve the list element:
    this._ulElement = dojo.query('ul.' + this._elementId)[0];
    
    // remember reference to this
    _this = this;

    // assign onclick event handler to all links:
    dojo.query('ul.' + this._elementId + ' a').forEach(function(inputElement)
    {
      inputElement.onclick = function(){ _this.open(inputElement)};
    });
    
    // setup the datastore:
    this._datastore = new dojo.data.ItemFileReadStore({url: '/shopping/json'});
    
    this._test = '_test';
  },

  open: function(catElement)
  {
    window.alert('open: ' + this._test);
    catElement.style.background = 'limegreen';
    
    // remember reference to this
    _this = this;
    _this.gotItem();
    
    this._datastore.fetchItemByIdentity(
    {
      identity: 'Kannen',
      onItem: _this.gotItem
    });
  },

  gotItem: function(item)
  {
    window.alert('gotItem: ' + this._test);
    //window.alert(this._datastore.getValue(item, 'name'));
  },

  _createCatElement: function()
  {
    // adds a new element to the list
    [...]
  },

  _empty: function()
  {
    // drops all elements
    [...]
  }
});
 
Naja, du legst ja einen Zeiger auf this an:
Code:
// remember reference to this
    _this = this;

Du nutzt diesen jedoch nicht:
Code:
window.alert('gotItem: ' + this._test);

Folgendes sollte jedoch wie gewünscht funktionieren:
Code:
window.alert('gotItem: ' + _this._test);
 
Hi,

hm, ja, so funktioniert's. Dojo.data scheint wohl ein new auf die Callbackfunktion anzuwenden, anders kann ich mir das nicht erklären.
Nur wollte ich von diesen Zeigern eigentlich irgendwie wieder weg kommen. Die hatte ich nur provisorisch eingeführt, da mir bisher keine bessere Lösung dafür eingefallen ist.
So könnte ich nämlich niemals zwei oder mehr der Objekte anlegen, da die _this Zeiger jeweils überschrieben werden würden.

Gibt's eine Möglichkeit, das ohne die _this Zeiger zu lösen? Ich komm' gerade nicht drauf ...
 
Jesus, jetzt weiss ich wieder, warum ich dies dojo so mag...es ist so saumässig dokumentiert, dass man es kaum beschreiben kann :rolleyes:
Die wichtigen Sachen darf man sich aus einer langen Textwurst in minimaler Fontgrösse heraussuchen :mad:

Lösung(hoffe ich)
Code:
this._datastore.fetchItemByIdentity(
    {
      identity: 'Kannen',
      scope:this,
      onItem: this.gotItem
    });
  },

dojo hat gesagt.:
The *scope* parameter.
// If a scope object is provided, all of the callback functions (onItem,
// onError, etc) will be invoked in the context of the scope object.
// In the body of the callback function, the value of the "this"
// keyword will be the scope object. If no scope object is provided,
// the callback functions will be called in the context of dojo.global

..und dojo.global ist das window-Objekt, deswegen wird ohne scope:this keine Membervariable gefunden.

Weiss der Geier, warum die das so gemacht haben, dass die Methoden standardmässig ihrem Objekt entrissen werden, das Gegenteil wäre eher logisch und normal.
 
Zurück