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

Relaterte artikler