Je peux utiliser this.variable
Pour accéder aux variables dans n'importe quelle partie du composant, sauf à l'intérieur des fonctions RxJS comme subscribe()
ou catch()
.
Dans l'exemple ci-dessous, je souhaite imprimer un message après avoir exécuté un processus:
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);
});
}
}
Lorsque j'exécute doSomething()
, j'obtiens non défini. Ce scénario peut être résolu à l'aide d'une variable locale:
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);
});
}
}
Je suppose que cela est lié au this
, cependant, pourquoi je ne peux pas accéder au this.message
À l'intérieur de la subscribe()
?
Cela n'a rien à voir avec rx ou angulaire, et tout à voir avec Javascript et TypeScript.
Je suppose que vous connaissez la sémantique de this
dans le contexte des invocations de fonctions en Javascript (sinon, il y a les explications ne manquent pas en ligne ) - ces sémantiques s'appliquent dans le premier extrait de code, bien sûr, et c'est la seule raison pour laquelle this.message
n'est pas défini dans subscribe()
. C'est juste Javascript.
Puisque nous parlons de TypeScript: les fonctions fléchées sont une construction TypeScript destinée (en partie) à contourner la maladresse de ces sémantiques en capturant lexicalement la signification de this
, ce qui signifie que this
à l'intérieur d'une fonction flèche === this
à partir du contexte externe.
Donc, si vous remplacez:
.subscribe(function(location) {
//this != this from outer context
console.log(this.message); //prints 'undefined'
});
par:
.subscribe((location) => {
//this == this from the outer context
console.log(this.message); //prints 'success'
});
Vous obtiendrez le résultat attendu.
Comme alternative à la réponse de @ drewmoore, si vous souhaitez avoir des fonctions externes, vous pouvez faire:
.subscribe((location) => dataHandler(location), (error) => errorHandler(error));
....
const dataHandler = (location) => {
...
}
En externalisant la fonction errorHandler
, elle peut être utilisée à plusieurs endroits (c'est-à-dire des abonnements). En ayant des fonctions de flèche (grasse), votre code capturera le contexte "ce" (comme expliqué dans la réponse de @ Drewmoore).
Ce qui manque, c'est la capacité à écrire ce qui suit et à gérer comme une fonction de flèche. Ce qui suit fonctionne et passe implicitement l'argument. Malheureusement AFAIK, vous ne pouvez pas capturer le contexte this
(peut-être utiliser bind
pour y parvenir, bien que cela rend le code plus verbeux dans l'ensemble).
.subscribe(dataHandler, errorHandler);
C'est tellement succinct! Mais hélas ne fonctionnera pas si le contexte est requis.