web-dev-qa-db-fra.com

js: accès à la portée de la classe parent

J'ai une classe jquery dans une classe normale en javascript. Est-il possible d'accéder à des variables dans la portée de la classe parente à partir d'une fonction de rappel dans la classe jquery?

Un exemple simple de ce que je veux dire est montré ci-dessous

var simpleClass = function () {    
    this.status = "pending";
    this.target = jqueryObject;
    this.updateStatus = function() {
        this.target.fadeOut("fast",function () {
           this.status = "complete"; //this needs to update the parent class 
        });
    };
};

Maintenant, dans l'exemple ci-dessus, la fonction de rappel tente d'accéder à la portée de l'objet jquery. existe-t-il un moyen d'accéder à la variable d'état dans la classe parente?

60
Sam

Vous définissez "this" sur une variable dans la fonction parent, puis vous l'utilisez dans la fonction interne.

var simpleClass = function () {         
    this.status = "pending";     
    this.target = jqueryObject;     

    var parent = this;

    this.updateStatus = function() {         
            this.jqueryObject.fadeOut("fast",function () {            
                parent.status = "complete"; //this needs to update the parent class          
            });     
        }; 
    }; 
96
Tom Brothers

Je posterai quand même cette réponse à cette vieille question car personne n'a encore posté cela auparavant.

Vous pouvez utiliser la méthode bind sur vos appels de fonction pour définir la portée à laquelle appartient this.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

Normalement, chaque fois que vous créez une méthode - this appartient à l'étendue actuelle de la fonction. Les variables de scope2 ne peuvent pas voir les variables de scope1.

par exemple.

function(){
    // scope 1
    this.baz = 'foo';

    function(){
        // scope 2
        this.baz // not defined
    };
};

avec la méthode bind vous pouvez définir la portée de this à l'intérieur de la fonction. Donc, en utilisant .bind(this), vous dites à la fonction appelée que sa propre portée de this est référée à la portée de la fonction parent, comme:

function(){
    // scope 1
    this.baz = 'foo';

    function(){
        // scope 1
        this.baz // foo
    }.bind(this);
};

dans votre cas, ce serait un exemple utilisant la méthode bind

var simpleClass = function () {    
    this.status = "pending";
    this.target = jqueryObject;
    this.updateStatus = function() {
        this.target.fadeOut("fast",function () {
           this.status = "complete"; //this needs to update the parent class 
        }.bind(this));
    }.bind(this);
};
32
ins0

Utilisez une fonction de flèche

Une fonction flèche n'a pas son propre this. La valeur this de la portée lexicale englobante est utilisée; les fonctions de flèche suivent les règles normales de recherche de variable. Ainsi, lors de la recherche de this qui n'est pas présent dans la portée actuelle, ils finissent par trouver this dans sa portée englobante.

Syntaxe de la fonction normale

function(param1, param2) {}

Syntaxe de la fonction flèche

(param1, param2) => {}

Utilisation

const simpleClass = function () {    
    this.status = "pending";
    this.target = jqueryObject;
    this.updateStatus = function() { 
        this.target.fadeOut("fast", () => { // notice the syntax here
           this.status = "complete"; // no change required here
        });
    };
};

Utilisation d'une fonction Flèche dans une classe ECMAScript 2015

class simpleClass {

    constructor() {
        this.status = 'pending';
        this.target = jqueryObject;
    }

    updateStatus() {
        this.target.faceOut('fast', () => {
            this.status = "complete";
        });
    }
}

const s = new simpleClass();
s.updateStatus();

Le code décrit ne fonctionne que dans navigateurs modernes .

6
Lucky Soni

Désolé m8. Vous devez imbriquer la référence dans les objets comme ceci:

var simpleClass = function () {
    var _root = this;
    this.status = "pending";
    this.target = jqueryObject;
    this.updateStatus = function() {
        this.root = _root;
        _root.target.fadeOut("fast",function () {
           this.status = "complete"; //this needs to update the parent class 
        });
    };
};

remarquez le var _root

2
Tokimon

En définissant "this" sur une variable à laquelle vous pouvez accéder facilement. Comme:

$("#ImageFile").change(function (e) {
    var image, file;
    var Parent=this;
    if ((file = Parent.files[0])) {
        var sFileExtension = file.name.split('.')[file.name.split('.').length - 1];

        if (sFileExtension === "jpg" || sFileExtension === "jpeg" || sFileExtension === "bmp" || sFileExtension === "png" || sFileExtension === "gif") {
            var reader = new FileReader();

            reader.onload = function (e) {
               alert(Parent.files[0].name);
            };
            reader.readAsDataURL(Parent.files[0]);
        }
        else { alert('Wrong file selected. Only jpg, jpeg, bmp, png and gif files are allowed.'); }
    }
})
2
Muhammad Awais

essaye ça:

   var sc = (function(scc){

    scc = {};

    scc.target = jQueryObject;


    scc.stt = "stt init";

    scc.updateStatus = function(){
        var elem = this;

        this.target.click(function(){
            elem.stt= "stt change";
            console.log(elem.stt);
        })

    }

    return scc;


}(sc || {}));

vous pouvez également définir votre objet cible comme variable privée

1
mdikici

Vous pouvez maintenir l'état à l'aide de variables de fermeture:

function simpleClass() {
   var _state = { status: "pending", target: jqueryObject; }

   this.updateStatus = function() {
      this.target.fadeOut("fast",function () {
         _state.status = "complete"; //this needs to update the parent class 
      });
   }
}

// Later...
var classInstance = new simpleClass();
0
Humberto