Van egy álnevet „ez a” géppel?

szavazat
72

Már megpróbálta levelet osztályú géppel, amely egy meghatározott módszer, amely működik, mint egy eseménykezelő callback a jQuery esemény.

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.
    }
}

Belül a onFocusIn eseménykezelő, géppel látja „ez”, hogy az „ez” az osztály. Azonban jQuery felülbírálja az e referencia, és beállítja a DOM objektum társított esemény.

Az egyik alternatíva az, hogy meghatározzák a lambda belül a kivitelező, mint az eseménykezelő, amely esetben géppel létrehoz egyfajta lezárás rejtett _this alias.

class Editor {
    textarea: JQuery;

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

A kérdésem az, van egy másik módja, hogy hozzáférjen a ezt a hivatkozást az eljáráson alapuló eseménykezelő segítségével géppel, hogy megoldja ezt a jQuery viselkedés?

A kérdést 06/10/2012 04:26
a forrás felhasználó
Más nyelveken...                            


12 válasz

szavazat
97

A hatályát thisis megmarad, amikor a nyíl függvény szintaxisa () => { ... }- itt van egy példa kivett géppel A JavaScript programozó .

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

Vegye figyelembe, hogy this.textmegadja neked Text from outer function, mert a nyíl függvény szintaxisa megőrzi a „lexikális körét”.

Válaszolt 06/10/2012 15:25
a forrás felhasználó

szavazat
21

Így amint nincs géppel biztosító mechanizmus eljárás minden esetben köteles ez thisa mutató (és ez nem csak egy jQuery kérdés.) Ez nem azt jelenti nincs kellően világos módon foglalkozni ezzel a kérdéssel. Amire szükség van, hogy létrehoz egy proxy a módszert, amely helyreállítja a thismutatót, mielőtt hívja a visszahívás. Ezután kell hogy csavarja el a visszahívási azzal, hogy a képviselők, mielőtt azt az eseményt. jQuery egy beépített mechanizmus erre hívják jQuery.proxy(). Íme egy példa a fenti kódot ezzel a módszerrel (megjegyzem, a hozzáadott $.proxy()hívást.)

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. 
    } 
} 

Ez egy elfogadható megoldás, de én személy szerint úgy találta, hogy a fejlesztők gyakran elfelejti, hogy tartalmazza a proxy hívást, így kitaláltam egy alternatív géppel alapú megoldás erre a problémára. Használata, a HasCallbacksbesorolás alatt csak annyit kell tennie, hogy abból az osztályt HasCallbacks, majd olyan módszereket előtaggal 'cb_'lesz a thismutató tartósan összekötött. Egyszerűen nem lehet hívni, hogy a módszer egy másik thismutató, amely a legtöbb esetben előnyös. Vagy a mechanizmus működik, így annak csak amelyik úgy találja, könnyebben használható.

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({});
Válaszolt 06/10/2012 06:28
a forrás felhasználó

szavazat
20

Hatálya alá tartozó egyes más választ, a nyíl szintaxis meghatározni a funkció révén utalást this, hogy mindig olvassa el a befoglaló osztály.

Tehát a választ a kérdésére, itt van két egyszerű megoldásokat.

Hivatkozás az eljárás a nyíl szintaxis

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

Adjuk meg a módszer segítségével a nyíl szintaxis

onFocusIn = (e: JQueryEventObject) => {
    var height = this.textarea.css('height');
}
Válaszolt 23/12/2013 05:27
a forrás felhasználó

szavazat
6

Akkor kötni egy tag függvény annak például a kivitelező.

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
    }
}

Egy másik változat szerint, csak azt köti, ha hozzá felvezető.

        this.textarea.focusin(onFocusIn.bind(this));
Válaszolt 20/05/2014 15:47
a forrás felhasználó

szavazat
3

Steven Ickman megoldása praktikus, de nem teljes. Danny Becket és Sam válaszok rövidebb és kézi, és nem ugyanabban az általános esetben, amelynek visszahívás, hogy szüksége van mind a dinamikus és közéjük egy távcsöves „ez” ugyanabban az időben. Ugrás a kódomat, ha a magyarázat alább TL; DR ...

Meg kell őrizni „ez a” dinamikus tartalom meghatározás használható könyvtár callback, és azt kell, hogy van egy „ez” a lexikális hatókör az osztály példányát. Azt állítják, hogy ez a legelegánsabb át a példány egy visszahívást generátor hatékonyan hagyta, hogy a paraméter lezárás az osztály példányát. A fordító azt mondja, ha nem fogadott ezzel. ÉN használ egy ilyen egyezmény hívja a lexikailag hatókörös paraméter „outerThis”, hanem „saját”, vagy más néven lehet jobb.

A használata a „this” kulcsszót ellopták az OO világban, amikor géppel elfogadja (az ECMAScript 6 specifikációk Felteszem), akkor nem keveri a szótanilag távcsöves koncepció és egy dinamikusan távcsöves fogalom, ha egy metódus egy másik entitás . Én egy kicsit bosszús ebben; Inkább egy „saját” címszó géppel, így én is viszont a lexikailag hatókörös objektum példányt le róla. Felváltva, JS lehetne újra igényel kifejezett first-helyzet „hívó” paramétert ha szükség van rá (és így szünet minden weboldalakat egy csapásra).

Itt a megoldás (kivágjuk a nagy osztály). Vegyünk egy gúnár, különösen az, ahogyan a módszereket nevezzük, és a test „dragmoveLambda” különösen:

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;
        }
    }

}
Válaszolt 21/03/2014 20:33
a forrás felhasználó

szavazat
3

Próbáld ezt

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
    }

}
Válaszolt 24/05/2013 02:47
a forrás felhasználó

szavazat
2

Használhatja js eval függvény: var realThis = eval('this');

Válaszolt 20/09/2014 13:13
a forrás felhasználó

szavazat
2

Géppel nem nyújt semmilyen extra módon (a szokványos JavaScript jelenti), hogy újra a „valódi” thishivatkozás kivételével thisremapping kényelmet nyújt a zsír nyíl lambda szintaxis (ami megengedhető egy back-compat szempontjából, mivel nem létező JS kód lehet használni a =>kifejezést).

Lehet küldeni egy javaslat, hogy a CodePlex helyén, hanem egy nyelvi tervezési szempontból ott valószínűleg sokat nem lehet itt történik, hiszen minden épeszű kulcsszó a fordító nyújthat talán már használatban vannak érvényben JavaScript kódot.

Válaszolt 06/10/2012 04:35
a forrás felhasználó

szavazat
1

Azt szembesültek hasonló problémával. Azt hiszem, akkor használja .each()sok esetben tartani this, mint egy másik értéket a későbbi eseményeket.

A JavaScript módon:

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

A géppel módon:

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

Remélem, ez segít valaki.

Válaszolt 16/06/2014 09:17
a forrás felhasználó

szavazat
0

Van sokkal egyszerűbb megoldás, mint a fenti válaszokat. Alapvetően esik vissza JavaScript segítségével kulcsszó funkció használata helyett „=>” konstrukciót, amely lefordítja az „ez” az osztályba „ez”

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'); 
    }
}
Válaszolt 11/05/2015 18:30
a forrás felhasználó

szavazat
0

Nézd meg ezt a blogbejegyzést http://lumpofcode.blogspot.com/2012/10/typescript-dart-google-web-toolkit-and.html , van egy részletes tárgyalása technikák rendezésére hívások és az egész géppel osztályok.

Válaszolt 06/12/2014 01:49
a forrás felhasználó

szavazat
0

Lehet tárolni a hivatkozás thisegy másik változó .. selftalán, és megtaláljuk a referencia így. Nem használok géppel, de ez a módszer, amely már sikeres nekem vanília javascript a múltban.

Válaszolt 06/10/2012 04:30
a forrás felhasználó

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