Είναι ένα ψευδώνυμο για το «αυτό» στη γραφομηχανή εκεί;

ψήφοι
72

Έχω προσπαθήσει να γράψει μια τάξη στη γραφομηχανή που έχει μια μέθοδο που ορίζεται οποία δρα ως χειρισμού συμβάντων επανάκλησης σε περίπτωση jQuery.

class Editor {
    textarea: JQuery;

    constructor(public id: string) {
        this.textarea = $(id);
        this.textarea.focusin(onFocusIn);
    }

    onFocusIn(e: JQueryEventObject) {
        var height = this.textarea.css('height'); // <-- This is not good.
    }
}

Στο πλαίσιο του χειρισμού συμβάντων onFocusIn, γραφομηχανή βλέπει «αυτό», όπως είναι το «αυτό» της κατηγορίας. Ωστόσο, jQuery αντικαθιστά την εν λόγω αναφορά και τον ορίζει στο αντικείμενο DOM συνδέονται με την εκδήλωση.

Μια εναλλακτική λύση είναι να καθορίσει ένα λάμδα εντός του κατασκευαστή, όπως το πρόγραμμα χειρισμού συμβάντων, οπότε γραφομηχανή δημιουργεί ένα είδος κλεισίματος με ένα κρυφό _this ψευδώνυμο.

class Editor {
    textarea: JQuery;

    constructor(public id: string) {
        this.textarea = $(id);
        this.textarea.focusin((e) => {
            var height = this.textarea.css('height'); // <-- This is good.
        });
    }
}

Η ερώτησή μου είναι, είναι ένας άλλος τρόπος για να αποκτήσετε πρόσβαση στην εν λόγω αναφορά εντός του χειρισμού συμβάντων μέθοδο που βασίζεται σε χρήση γραφομηχανή, για να ξεπεραστεί αυτή η συμπεριφορά jQuery εκεί;

Δημοσιεύθηκε 06/10/2012 στις 04:26
πηγή χρήστη
Σε άλλες γλώσσες...                            


12 απαντήσεις

ψήφοι
97

Το πεδίο εφαρμογής της thisδιατηρείται κατά τη χρήση του σύνταξη της συνάρτησης βέλος () => { ... }- εδώ είναι ένα παράδειγμα από γραφομηχανή Για την Javascript για προγραμματιστές .

var ScopeExample = { 
  text: "Text from outer function", 
  run: function() { 
    setTimeout( () => { 
      alert(this.text); 
    }, 1000); 
  } 
};

Σημειώστε ότι this.textσας δίνει Text from outer functionεπειδή η σύνταξη βέλος λειτουργία διατηρεί την «λεξιλογικό πεδίο».

Απαντήθηκε 06/10/2012 στις 15:25
πηγή χρήστη

ψήφοι
21

Έτσι, όπως αναφέρεται, δεν υπάρχει μηχανισμός γραφομηχανή για την εξασφάλιση μιας μεθόδου είναι πάντα βέβαιο ότι θα είναι thisδείκτης (και αυτό δεν είναι απλώς ένα ζήτημα jQuery.) Αυτό δεν σημαίνει ότι δεν υπάρχει ένας σχετικά απλός τρόπος για να αντιμετωπίσει αυτό το ζήτημα. Αυτό που χρειάζεστε είναι να δημιουργήσει ένα πληρεξούσιο για τη μέθοδο που αποκαθιστά το thisδείκτη πριν από την κλήση επανάκλησης σας. Στη συνέχεια, πρέπει να τυλίξετε επανάκλησης σας με αυτό το πληρεξούσιο πριν από τη διοχέτευση στην εκδήλωση. jQuery έχει ένα ενσωματωμένο μηχανισμό για αυτό που ονομάζεται jQuery.proxy(). Εδώ είναι ένα παράδειγμα των παραπάνω κωδικό σας χρησιμοποιώντας αυτή τη μέθοδο (παρατηρήστε την προστιθέμενη $.proxy()κλήση.)

class Editor { 
    textarea: JQuery; 

    constructor(public id: string) { 
        this.textarea = $(id); 
        this.textarea.focusin($.proxy(onFocusIn, this)); 
    } 

    onFocusIn(e: JQueryEventObject) { 
        var height = this.textarea.css('height'); // <-- This is not good. 
    } 
} 

Αυτή είναι μια λογική λύση, αλλά έχω προσωπικά διαπιστώσει ότι οι προγραμματιστές συχνά ξεχνάμε να περιλαμβάνουν την πρόσκληση μεσολάβησης έτσι έχω καταλήξει σε μια εναλλακτική γραφομηχανή που βασίζεται λύση σε αυτό το πρόβλημα. Χρησιμοποιώντας, η HasCallbacksτάξη κάτω από το μόνο που χρειάζεται να κάνετε είναι αντλούν την τάξη σας από HasCallbacksκαι, στη συνέχεια, κάθε μέθοδος πρόθεμα 'cb_'θα έχουν τους thisδείκτη μόνιμα συνδεδεμένο. Δεν μπορείτε απλά να καλέσετε τη μέθοδο αυτή με διαφορετικό thisδείκτη ο οποίος στις περισσότερες περιπτώσεις είναι προτιμότερη. Είτε ο μηχανισμός λειτουργεί τόσο μόνο του ανάλογα με το ποια θα βρείτε πιο εύκολο στη χρήση.

class HasCallbacks {
    constructor() {
        var _this = this, _constructor = (<any>this).constructor;
        if (!_constructor.__cb__) {
            _constructor.__cb__ = {};
            for (var m in this) {
                var fn = this[m];
                if (typeof fn === 'function' && m.indexOf('cb_') == 0) {
                    _constructor.__cb__[m] = fn;                    
                }
            }
        }
        for (var m in _constructor.__cb__) {
            (function (m, fn) {
                _this[m] = function () {
                    return fn.apply(_this, Array.prototype.slice.call(arguments));                      
                };
            })(m, _constructor.__cb__[m]);
        }
    }
}

class Foo extends HasCallbacks  {
    private label = 'test';

    constructor() {
        super();

    }

    public cb_Bar() {
        alert(this.label);
    }
}

var x = new Foo();
x.cb_Bar.call({});
Απαντήθηκε 06/10/2012 στις 06:28
πηγή χρήστη

ψήφοι
20

Όπως καλύπτονται από κάποια από τις άλλες απαντήσεις, χρησιμοποιώντας τη σύνταξη βέλος για να ορίσουμε μια συνάρτηση προκαλεί αναφορές σε thisαναφορά πάντα με την κατηγορία που περικλείει.

Έτσι για να απαντήσω στην ερώτησή σας, εδώ είναι δύο απλές λύσεις.

Αναφορά της μεθόδου χρησιμοποιώντας τη σύνταξη βέλος

constructor(public id: string) {
    this.textarea = $(id);
    this.textarea.focusin(e => this.onFocusIn(e));
}

Καθορίστε τη μέθοδο χρησιμοποιώντας τη σύνταξη βέλος

onFocusIn = (e: JQueryEventObject) => {
    var height = this.textarea.css('height');
}
Απαντήθηκε 23/12/2013 στις 05:27
πηγή χρήστη

ψήφοι
6

Μπορείτε να συνδέσετε μια συνάρτηση-μέλος στο παράδειγμα του στον κατασκευαστή.

class Editor {
    textarea: JQuery;

    constructor(public id: string) {
        this.textarea = $(id);
        this.textarea.focusin(onFocusIn);
        this.onFocusIn = this.onFocusIn.bind(this); // <-- Bind to 'this' forever
    }

    onFocusIn(e: JQueryEventObject) {
        var height = this.textarea.css('height');   // <-- This is now fine
    }
}

Εναλλακτικά, απλά δεσμεύει όταν προσθέτετε το χειριστή.

        this.textarea.focusin(onFocusIn.bind(this));
Απαντήθηκε 20/05/2014 στις 15:47
πηγή χρήστη

ψήφοι
3

λύση Steven Ickman είναι βολικό, αλλά ελλιπής. Danny Μπέκετ και οι απαντήσεις του Σαμ είναι μικρότερη και πιο εγχειρίδιο, και αποτυγχάνουν στην ίδια γενική περίπτωση που έχει επανάκλησης που χρειάζεται τόσο δυναμικές και λεξιλογικά scoped «αυτό» την ίδια στιγμή. Μετάβαση στο κωδικό μου αν μου εξήγηση είναι κάτω TL? DR ...

Θα πρέπει να διατηρηθεί «η» για τη δυναμική οριοθέτηση του πεδίου για χρήση με callbacks βιβλιοθήκη, και θα πρέπει να έχουν ένα «αυτό» με λεξιλογικό οριοθέτηση του πεδίου στην περίπτωση τάξη. Υποστηρίζω ότι είναι πιο κομψό να περάσει το παράδειγμα σε μια γεννήτρια επανάκλησης, αφήνοντας ουσιαστικά το κλείσιμο των παραμέτρων πάνω από το παράδειγμα της κατηγορίας. Ο συντάκτης σας λέει αν χάσατε κάτι τέτοιο. Χρησιμοποιώ μια σύμβαση καλώντας τα λεκτικά με εύρος παραμέτρου «outerThis», αλλά «αυτο» ή ένα άλλο όνομα θα μπορούσε να είναι καλύτερη.

Η χρήση του «αυτό» λέξη-κλειδί κλαπεί από τον κόσμο OO, και όταν γραφομηχανή, η επιτροπή ενέκρινε (από ECMAScript 6 specs υποθέτω), που συγχέονται μια λεκτική scoped έννοια και δυναμικά με εύρος έννοια, κάθε φορά που μια μέθοδο που ονομάζεται από μια διαφορετική οντότητα . Είμαι λίγο θυμωμένη σε αυτό? Θα προτιμούσα ένα «εγώ» λέξη-κλειδί στη γραφομηχανή, έτσι ώστε να μπορώ να παραδώσει το λεξιλογικά με εύρος παράδειγμα αντικειμένου μακριά από αυτό. Εναλλακτικά, JS θα μπορούσε να επαναπροσδιοριστούν να απαιτεί ρητή παράμετρο πρώτη θέση «καλών» όταν χρειάζεται (και, επομένως, να σπάσει όλα τα ιστοσελίδες μονομιάς).

Εδώ είναι η λύση μου (αποκόπηκαν από μια μεγάλη κατηγορία). Πάρτε μια αρσενική χήνα, ιδίως για τον τρόπο καλούνται οι μέθοδοι, και το σώμα του «dragmoveLambda» ιδίως:

export class OntologyMappingOverview {

initGraph(){
...
// Using D3, have to provide a container of mouse-drag behavior functions
// to a force layout graph
this.nodeDragBehavior = d3.behavior.drag()
        .on("dragstart", this.dragstartLambda(this))
        .on("drag", this.dragmoveLambda(this))
        .on("dragend", this.dragendLambda(this));

...
}

dragmoveLambda(outerThis: OntologyMappingOverview): {(d: any, i: number): void} {
    console.log("redefine this for dragmove");

    return function(d, i){
        console.log("dragmove");
        d.px += d3.event.dx;
        d.py += d3.event.dy;
        d.x += d3.event.dx;
        d.y += d3.event.dy; 

        // Referring to "this" in dynamic scoping context
        d3.select(this).attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });

        outerThis.vis.selectAll("line")
            .filter(function(e, i){ return e.source == d || e.target == d; })
            .attr("x1", function(e) { return e.source.x; })
            .attr("y1", function(e) { return e.source.y; })
            .attr("x2", function(e) { return e.target.x; })
            .attr("y2", function(e) { return e.target.y; });

    }
}

dragging: boolean  =false;
// *Call* these callback Lambda methods rather than passing directly to the callback caller.
 dragstartLambda(outerThis: OntologyMappingOverview): {(d: any, i: number): void} {
        console.log("redefine this for dragstart");

        return function(d, i) {
            console.log("dragstart");
            outerThis.dragging = true;

            outerThis.forceLayout.stop();
        }
    }

dragendLambda(outerThis: OntologyMappingOverview): {(d: any, i: number): void}  {
        console.log("redefine this for dragend");

        return function(d, i) {
            console.log("dragend");
            outerThis.dragging = false;
            d.fixed = true;
        }
    }

}
Απαντήθηκε 21/03/2014 στις 20:33
πηγή χρήστη

ψήφοι
3

Δοκιμάστε αυτό

class Editor 
{

    textarea: JQuery;
    constructor(public id: string) {
        this.textarea = $(id);
        this.textarea.focusin((e)=> { this.onFocusIn(e); });
    }

    onFocusIn(e: JQueryEventObject) {
        var height = this.textarea.css('height'); // <-- This will work
    }

}
Απαντήθηκε 24/05/2013 στις 02:47
πηγή χρήστη

ψήφοι
2

Μπορείτε να χρησιμοποιήσετε js eval συνάρτηση: var realThis = eval('this');

Απαντήθηκε 20/09/2014 στις 13:13
πηγή χρήστη

ψήφοι
2

Γραφομηχανή δεν παρέχει καμία επιπλέον τρόπο (πέρα από το κανονικό το JavaScript μέσο) για να πάρει πίσω την «πραγματική» thisαναφορά, εκτός από thisχαρτογράφηση ευκολία που παρέχεται στη σύνταξη λίπος βέλος λ (που είναι επιτρεπτό από ένα back-compat προοπτική, δεδομένου ότι δεν υπάρχοντα κώδικα JS θα μπορούσε να είναι με χρήση =>της έκφρασης).

Θα μπορούσατε να προσθέσετε μια πρόταση στο χώρο CodePlex, αλλά από τη σκοπιά του σχεδιασμού γλώσσα κατά πάσα πιθανότητα δεν υπάρχουν πολλά που μπορεί να συμβεί εδώ, δεδομένου ότι κάθε λογικός λέξη-κλειδί ο compiler θα μπορούσε να προσφέρει ίσως να είναι ήδη σε χρήση από υφιστάμενα κώδικα JavaScript.

Απαντήθηκε 06/10/2012 στις 04:35
πηγή χρήστη

ψήφοι
1

Έχω αντιμετωπίσει ένα παρόμοιο πρόβλημα. Νομίζω ότι μπορείτε να χρησιμοποιήσετε .each()σε πολλές περιπτώσεις να κρατήσει thisως διαφορετική τιμή για αργότερα γεγονότα.

Ο τρόπος JavaScript:

$(':input').on('focus', function() {
  $(this).css('background-color', 'green');
}).on('blur', function() {
  $(this).css('background-color', 'transparent');
});

Ο τρόπος με γραφομηχανή:

$(':input').each((i, input) => {
  var $input = $(input);
  $input.on('focus', () => {
    $input.css('background-color', 'green');
  }).on('blur', () => {
    $input.css('background-color', 'transparent');
  });
});

Ελπίζω ότι αυτό βοηθά κάποιος.

Απαντήθηκε 16/06/2014 στις 09:17
πηγή χρήστη

ψήφοι
0

Υπάρχει πολύ πιο απλή λύση από όλες τις παραπάνω απαντήσεις. Βασικά θα πέσει πίσω στο το JavaScript, χρησιμοποιώντας το πλήκτρο λειτουργίας λέξη αντί για τη χρήση «=>» κατασκευή η οποία θα μεταφράσει το «αυτή» στην κατηγορία «αυτό»

class Editor {
    textarea: JQuery;

    constructor(public id: string) {
        var self = this;                      // <-- This is save the reference
        this.textarea = $(id);
        this.textarea.focusin(function() {   // <-- using  javascript function semantics here
             self.onFocusIn(this);          //  <-- 'this' is as same as in javascript
        });
    }

    onFocusIn(jqueryObject : JQuery) {
        var height = jqueryObject.css('height'); 
    }
}
Απαντήθηκε 11/05/2015 στις 18:30
πηγή χρήστη

ψήφοι
0

Ελέγξτε έξω αυτό το blog post http://lumpofcode.blogspot.com/2012/10/typescript-dart-google-web-toolkit-and.html , έχει μια λεπτομερή συζήτηση των τεχνικών για την οργάνωση κλήσεις εντός και μεταξύ των κατηγοριών γραφομηχανή.

Απαντήθηκε 06/12/2014 στις 01:49
πηγή χρήστη

ψήφοι
0

Θα μπορούσατε να αποθηκεύσετε την αναφορά σας με thisτο άλλο μεταβλητή .. selfίσως και πρόσβαση στην αναφορά με αυτόν τον τρόπο. Δεν χρησιμοποιώ γραφομηχανή, αλλά αυτό είναι μια μέθοδος που είναι ήδη επιτυχημένη για μένα με javascript βανίλια στο παρελθόν.

Απαντήθηκε 06/10/2012 στις 04:30
πηγή χρήστη

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more