2012-04-11 29 views
1

Ich schreibe eine Javascript-App, die ein HTML-Dokument über AJAX erhält, und es dann verarbeiten muss, um Ereignis-Listener (insbesondere Bootstrap-Popovers) an die darin enthaltenen Elemente anzuhängen. Ich habe Schwierigkeiten, die Zuhörer anzuhängen, und ich glaube, es ist ein Problem mit dem Umfang. Hier ist der relevante Code:Javascript-Callbacks innerhalb eines Objekts

var App = function(site){ 

    this.load = function(data, func){ 
    $('div.ajax').html(data); 
    func(); 
    } 

    this.dispatch = function(data){ 

    if(data.indexOf('from_server') !== -1){ 
     this.load(data, this.process); 
     console.log('Loaded view from Matisse.'); 
     return true; 
    } 

    } 

    this.process = function(){ 
    this.popovers('from_server'); 
    } 

    this.popovers = function(el){ 
    var that = this; 
    $('img.artwork.gallery', el).each(function(){ 
     $(this).popover({ trigger: 'hover', content: that.popoverPopulate(this) }); 
    }); 
    } 

    this.popoverPopulate = function(el){ 
    return $(el).next('div.popover_content').html(); 
    } 
} 

var APP = new App(); 

$.ajax({blah: blah, success: function(data){ APP.dispatch(data); }}); 

... 

Das Problem (glaube ich) ist der func() Anruf in this.load. Wenn ich es this.process() übergebe, dann scopes das 'this' zum Fenster, und es gibt einen Fehler. Wenn ich this.process übergebe, ist es ein Lambda, das erstellt wird, und es schlägt immer noch fehl. Wenn ich this.func() rufe, tritt das gleiche Problem auf.

Wie kann ich entweder a) den Bereich innerhalb des App-Objekts mit dem Rückruf behalten, oder b) dieses Chaos reorganisieren, um den Handler nach dem Laden aufzurufen?

Antwort

5

Ich könnte mir vorstellen, Sie var that=this Scoping Trick auf alle Methoden verwenden möchten:

var App = function(site){ 

    var that = this; 

    this.load = function(data, func){ 
    $('div.ajax').html(data); 
    func(); 
    } 

    this.dispatch = function(data){ 

    if(data.indexOf('from_server') !== -1){ 
     that.load(data, that.process); 
     console.log('Loaded view from Matisse.'); 
     return true; 
    } 

    } 

    this.process = function(){ 
    that.popovers('from_server'); 
    } 

    this.popovers = function(el){ 
    $('img.artwork.gallery', el).each(function(){ 
     $(that).popover({ trigger: 'hover', content: that.popoverPopulate(this) }); 
    }); 
    } 

    this.popoverPopulate = function(el){ 
    return $(el).next('div.popover_content').html(); 
    } 
} 
+0

akzeptiert, weil es in erster kam, aber ein großes Lob auch an Ilia. Ich hatte das schon getan, als die Antwort kam, aber danke. Die Hörer hängen immer noch nicht an, aber ich denke, das ist ein Problem mit Bootstrap, nicht mein Javascript. –

+0

Ah, ja - Ich habe Bootstrap nicht benutzt, daher kenne ich seine Probleme nicht. Viel Glück! (Auch, ich werde die Kudos @Ilia Sekunde - zwei Minuten ist nicht nichts.) – JKing

1

dies bezieht sich auf den Kontext, in dem es zur Zeit verwendet wird. Also, wenn Sie this.process tun, wird es auf das Fenster zielen. Wenn Sie App.load(data, App.process) tun, dann zielt es auf die Prozessfunktion innerhalb des App Objekts ab.

4

Etwas wie folgt aus:

var App = function(site){ 
    var self = this; //-<!!! 

    this.load = function(data, func){ 

    ... 

    this.dispatch = function(data){ 
     if(data.indexOf('from_server') !== -1){ 
      self.load(data, self.process); 
    ... 
+1

hahahaha, Ich mag wirklich Ihre "Achtung" Kommentar! Das ist ausgezeichnet. Auch in der letzten Zeile (vor dem "...") möchten Sie wahrscheinlich "self" statt "this" beim Methodenaufruf verwenden, genauso wie die Referenz, die Sie übergeben, nein? Oder wird "das" immer noch das Objekt und nicht das "Fenster" an diesem Punkt sein? – JKing

+1

:-) Du hast recht. –

Verwandte Themen