javascript - Få tilgang til variabler erklært i en komponent fra en RxJS subscribe()-funksjon
Jeg kan bruke this.variable for å få tilgang til variabler i hvilken som helst del av komponenten, bortsett fra inne i RxJS-funksjoner som subscribe() eller catch().
I eksemplet nedenfor vil jeg skrive ut en melding etter å ha kjørt en prosess:
import {Component, View} from 'angular2/core';
@Component({
selector: 'navigator'
})
@View({
template: './app.component.html',
styles: ['./app.component.css']
})
export class AppComponent {
message: string;
constructor() {
this.message = 'success';
}
doSomething() {
runTheProcess()
.subscribe(function(location) {
console.log(this.message);
});
}
}
Når jeg kjører doSomething(), får jeg undefined. Dette scenariet kan løses ved å bruke en lokal variabel:
import {Component, View} from 'angular2/core';
@Component({
selector: 'navigator'
})
@View({
template: './app.component.html',
styles: ['./app.component.css']
})
export class AppComponent {
message: string;
constructor() {
this.message = 'success';
}
doSomething() {
// assign it to a local variable
let message = this.message;
runTheProcess()
.subscribe(function(location) {
console.log(message);
});
}
}
Jeg antar dette er relatert til this, men hvorfor kan jeg ikke få tilgang til this.message inne i subscribe()?
Svar #1
Dette har ingenting å gjøre med rx eller angular, og alt å gjøre med Javascript og Typescript.
Jeg antar at du er kjent med semantikken til this i konteksten av funksjonskall i Javascript (hvis ikke, finnes det mange forklaringer på nettet) - denne semantikken gjelder selvfølgelig i det første kodeeksemplet, og det er den eneste grunnen til at this.message er udefinert inne i subscribe() der. Det er bare Javascript.
Siden vi snakker om Typescript: Pilefunksjoner er en Typescript-konstrukjon som er ment (delvis) å omgå det vanskelige med disse semantikkene ved å leksikalsk fange meningen med this, noe som betyr at this inne i en pilefunksjon === this fra den ytre konteksten.
Så, hvis du erstatter:
.subscribe(function(location) {
//this != this from outer context
console.log(this.message); //prints 'undefined'
});
av :
.subscribe((location) => {
//this == this from the outer context
console.log(this.message); //prints 'success'
});
Du vil få det forventede resultatet ditt.
