2011-08-08 13 views
12

I zdefiniować następujące MyClass i jego metod w skrypcie użytkownika:Wywołuje metodę javascript obiektu od wewnątrz wywołania zwrotnego

function MyClass() { 
    this.myCallback = function() { 
     alert("MyClass.myCallback()"); 
    }; 

    this.startRequest = function() { 
     GM_xmlhttpRequest({ 
      'method': 'GET', 
      'url': "http://www.google.com/", 
      'onload': function (xhr) { 
       myClassInstance.myCallback(); 
      } 
     }); 
    }; 
} 

var myClassInstance = new MyClass(); 
myClassInstance.startRequest(); 

Ten skrypt działa i metoda myCallback() jest wywoływana raz na GM_xmlhttpRequest uzupełnia.

Jednak działa tylko dlatego, że wywołanie zwrotne onload odnosi się do globalnej zmiennej myClassInstance. Gdybym zaktualizować onload oddzwanianie do:

'onload': function (xhr) { 
    this.myCallback(); 
} 

Następnie pojawia się (chrom) błąd:

Uncaught TypeError: Object [object DOMWindow] has no method 'myCallback'.

Wydaje this jest oceniana w niewłaściwym kontekście.

Czy istnieje sposób wywołania metody myCallback() z myClassInstance bez konieczności uciekania się do używania zmiennej globalnej?

Odpowiedz

23

Zapisz poprawną this, gdy jest w zakresie, do zmiennej. Wtedy można go odwołać później:

this.startRequest = function() { 
    var myself = this; 
    GM_xmlhttpRequest({ 
     'method': 'GET', 
     'url': "http://www.google.com/", 
     'onload': function (xhr) { 
      myself.myCallback(); 
     } 
    }); 
}; 
+0

+1 pobili mnie do tego. – JAAulde

+4

+1 Właśnie skończyłem moją godzinę sesji head slamming. Dziękuję Ci. :) – Anthony

2

Store odwołanie do instancji i używać go:

function MyClass() { 
    this.myCallback = function() { 
     alert("MyClass.myCallback()"); 
    }; 

    var instance = this; 

    instance.startRequest = function() { 
     GM_xmlhttpRequest({ 
      'method': 'GET', 
      'url': "http://www.google.com/", 
      'onload': function (xhr) { 
       instance.myCallback(); 
      } 
     }); 
    }; 
} 
4

najprostsze rozwiązanie, jak już wskazywano, jest stworzenie aliasu dla this który pozostaje w ramach. Najpopularniejszymi nazwami dla aliasu są: self lub that, ale cokolwiek działa, naprawdę.

Innym alternatywnym (co może być lub może nie być lepsze, w zależności od przypadku zastosowania) wiąże się sposobem w funkcji „zwykłym” i za pomocą, że zamiast:

var f = this.callback.bind(this); 

... 
'onload': function(){ 
    f(); 
} 

wiążą nie jest wspierane na starym przeglądarki, ale możesz znaleźć alternatywy w wielu frameworkach JS. Podany przeze mnie przykład nie wygląda tak dobrze, ale może być bardzo wygodny, gdy chcesz przekazać swoją metodę bezpośrednio jako funkcję zwrotną (możesz również uzyskać częściową funkcję aplikacji i jest bardzo zgrabna)

+2

Uważaj na 'self' z powodu' window.self'. – Jeremy

Powiązane problemy