2017-05-10 1 views
1

J'ai essayé de mon mieux de reproduire l'erreur en dehors de mon contexte, mais j'ai échoué, donc je vais devoir fournir avec elle.Comportement de portée inattendue dans les objets Javascript

code:

var view; 

widget = { 
    activated: false, 
    close: function(){ 
     this.view.popupManager.enabled = false; 
    } 
} 

view = new MapView({ 
}).then(function(){ //then is triggered when fully loaded; 
    console.log(this.popupManager) //Object! 
    widget.activated = true; 
    widget.view = this; 
} 

console.log(view.popupManager) //Undefined, not loaded yet 

$('#my_button').click(function(){ 
    if(widget.activated){ 
     widget.close() //this.view.popupManager is undefined 
    } 
}) 

Cela utilise l'API Javascript 4.3 Esri, mais il ne semble pas être l'API, mais certains misuderstanding de ma part sur la façon dont fonctionne la portée en Javascript.

Comme vous pouvez le voir, même si je ne convoquent que widget.close si view est complètement chargé, il référençant encore l'ancien, et non objet complètement chargé

Qu'est-ce que je manque?

+0

Vous décrivez exactement ce qui se passe: Ce n'est pas chargé *encore*. – Bergi

+0

Cela fonctionne-t-il mieux si vous remplacez 'widget.view = this'; avec 'widget.view = view;'? – CaptEmulation

+0

@Bergi si "then" est appelé cela signifie qu'il est chargé – Mojimi

Répondre

4

Le problème ici est que this n'est pas toujours ce que vous pensez qu'il est. Il y a un couple de this s dans votre code, et chacun est différent.

Bienvenue à JavaScript souvent mal compris this.

Dans le code

widget = { 
    activated: false, 
    close: function(){ 
     this.view.popupManager.enabled = false; 
    } 
} 

this se référera à la widget.

maintenant dans le code dans la fonction de rappel then, this se rapportera à l'objet window, de sorte que vous dites essentiellement widget.view = window. Ce this est probablement celui qui vous attrape.

Je pense que ce que vous entendez est de définir la vue de la nouvelle vue du widget, dans ce cas, vous devez mettre à jour le code comme suit:

var view; 

widget = { 
    activated: false, 
    close: function(){ 
     this.view.popupManager.enabled = false; 
    } 
} 

view = new MapView({ 
}).then(function() { 
    widget.activated = true; 
    widget.view = view; // set the widget's view correctly 
}); 

$('#my_button').click(function(){ 
    if(widget.activated){ 
     widget.close(); 
    } 
});