访问变量从RxJS subscribe()函数中声明了一个组件

Access variables declared a component from a RxJS subscribe() function

本文关键字:组件 一个 声明 函数 变量 RxJS subscribe 访问      更新时间:2023-09-26

我可以使用this.variable访问组件任何部分的变量,但在RxJS函数(如subscribe()catch())内部除外。

在下面的例子中,我想在运行一个进程后打印一条消息:

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

当我运行doSomething()时,我得到未定义。这个场景可以使用一个局部变量来解决:

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

我想这与this有关,但为什么我不能访问subscribe()内部的this.message

这与rx或angular无关,一切都与Javascript和Typescript有关。

我假设您熟悉Javascript中函数调用上下文中this的语义(如果不熟悉,在线上不乏解释)——当然,这些语义适用于第一个代码段,这也是this.messagesubscribe()中未定义的唯一原因。这只是Javascript。

既然我们谈论的是打字:箭头函数是一种Typescript构造,旨在(部分)通过词汇捕捉this的含义来避免这些语义的尴尬,这意味着箭头函数中的this从外部上下文===this

所以,如果你更换:

.subscribe(function(location) {
        //this != this from outer context 
        console.log(this.message); //prints 'undefined'
    });

发件人:

.subscribe((location) => {
     //this == this from the outer context 
        console.log(this.message); //prints 'success'
    });

你会得到预期的结果。

作为@drewmoore答案的替代方案,如果您希望拥有外部功能,您可以执行:

 .subscribe((location) => dataHandler(location), (error) => errorHandler(error));
 ....
 const dataHandler = (location) => {
     ...
 }

通过将errorHandler函数外部化,它可以在多个地方使用(即订阅)。通过使用as(fat)箭头函数,您的代码将捕获"this"上下文(如@Drewmoore的回答中所讨论的)。

缺少的是编写以下内容的能力,以及像箭头函数一样处理的能力。以下操作将隐式传递参数。不幸的是,AFAIK无法捕获this上下文(也许可以使用bind来实现这一点,尽管这会使代码总体上更加冗长)。

 .subscribe(dataHandler, errorHandler);

这太简洁了!但是,如果需要上下文的话,唉,这是行不通的。

相关文章: