Steven Ickman rozwiązanie jest przydatne, ale niekompletne. Danny Becket i odpowiedzi Sama są krótsze i bardziej ręczne, a nie w tym samym ogólnym przypadku konieczności wywołania zwrotnego, który wymaga zarówno dynamiczne i leksykalnie scoped „to” w tym samym czasie. Przejdź do mojego kodu, jeśli moje wyjaśnienie poniżej TL; DR ...
Muszę zachować „to” dla dynamicznego rozsyłania do użytku z callbacków bibliotecznych, i muszę mieć „to” z leksykalnego zakresu celem instancji klasy. Uważam, że jest to najbardziej elegancki przekazać instancję do generatora wywołania zwrotnego, pozwalając skutecznie zamknięcie parametru nad instancji klasy. Kompilator informuje, jeśli brakowało robić. Używam konwencję wywołanie leksykalnie zawężona parametr „outerThis”, ale „ja” lub inna nazwa może być lepiej.
Korzystanie z „tego” hasła został skradziony ze świata oo, a gdy maszynopis przyjęła go (z ECMAScript 6 specyfikacje przypuszczam), że pomylili się leksykalnie scoped koncepcję i dynamicznie scoped pojęcie, gdy metoda jest wywoływana przez inny podmiot , Jestem trochę dotknięty w tym; Wolałbym „ja” słowo kluczowe w maszynie tak, że mogę przekazać zawężona leksykalnie instancji obiektu z dala od niego. Alternatywnie, JS może być na nowo, aby wymagać pierwszej pozycji parametru explicit „rozmówcy”, kiedy jest to konieczne (a więc złamać wszystkie strony internetowe w jednym zamachem).
Oto moje rozwiązanie (wycięto z dużej klasy). Popatrzeć w szczególności w drodze metody są nazywane i ciało „dragmoveLambda” w szczególności:
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;
}
}
}