javascript - Mister denne referansen i $scope.$on-hendelsen
Jeg registrerer "$routeChangeSuccessEvent" fra Angularjs ved å sette tilbakekallingsfunksjonen. Når hendelsen utløses, kan jeg ikke få tilgang til min controllers instans med "this". Den nåværende this-instansen er udefinert.
Min komplette TypeScript-kode:
export class Ctlr {
static $inject = ["$rootScope","$route"];
constructor(private $scope: ng.IRootScopeService) {
this.Scope = $scope;
this.Title = "";
//this.Scope.$on("$routeChangeSuccessEvent", this.onRouteChangeStart);
this.RegisterEvents();
}
private RegisterEvents(): void {
this.Scope.$on("$routeChangeSuccessEvent",(event: ng.IAngularEvent, args: any) => {
//this is undefined
console.log(this);
});
}
public Scope: ng.IScope;
public Title: string;
public onRouteChangeStart(event: ng.IAngularEvent, args: any) {
//this is undefined
this.Title = args.$$route.name);
}
}
}
Jeg kan få tilgang til Title-egenskapen med:
private RegisterEvents(): void {
var ref = this.Title;
this.Scope.$on("$routeChangeSuccessEvent",(event: ng.IAngularEvent, args: any) => {
ref = args.$$route.name;
});
}
Men det er ikke en virkelig løsning fordi AngularJS ikke oppdaterer visningen sin. Det ser ut til at jeg ikke fikk tak i riktig referanse. Hvis det ikke er mulig, virker det som om hele AngularJS-hendelsene ikke kan brukes - det kan ikke være mulig?
Jeg fant heller ikke noen emne om denne merkelige oppførselen. Finnes det en løsning på dette problemet?
Svar #1
Omfanget endres når en tilbakeringing utløses, derfor blir this udefinert.
Ditt andre eksempel på å gjøre:
var ref = this.Title;
Faktisk oppretter det bare en -kopi- av Title siden det er en primitiv type (string). Dette er grunnen til at det heller ikke fungerte. Å oppdatere ref oppdaterer ikke this.Title.
Den vanlige løsningen på dette, er å starte definisjonen som:
var vm = this;
...
private RegisterEvents(): void {
this.Scope.$on("$routeChangeSuccessEvent",(event: ng.IAngularEvent, args: any) => {
//this is undefined
console.log(vm);
});
}
Så i stedet for å bruke this overalt, vil du bruke vm. Merk at vm kan kalles hva du vil. Den viktige delen er at du fanger en referanse til this i et område der this er det du vil bruke i en callback. Dette fungerer fordi this ikke er en primitiv type, siden det er et objekt, og i stedet for å ta en kopi, tar det en referanse.
Ditt andre alternativ er å bruke bind som du kan anvende på hvilken som helst funksjon, denne funksjonen forteller i hovedsak JavaScript hva this vil tilsvare. For eksempel.
$scope.$on("SomeEventHere", someCallbackFunction.bind(this));
Det er et spørsmål om preferanse hvilken du bruker her, men generelt ser jeg folk bruke var something=this;-metoden.
Svar #2
Det er fordi dette alltid refererer til dets overordnede som nå er funksjonen. Så hvis du ville, kunne du gjøre dette:
private RegisterEvents(): void {
var ref = this;
this.Scope.$on("$routeChangeSuccessEvent",(event: ng.IAngularEvent, args: any) => {
console.log(ref);
});
}
