【问题标题】:Access variables declared a component from a RxJS subscribe() function访问从 RxJS subscribe() 函数声明的组件的变量
【发布时间】:2016-01-07 04:34:29
【问题描述】:

我可以使用this.variable 访问组件任何部分的变量,除了像subscribe()catch() 这样的RxJS 函数内部。

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

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() 时,我得到undefined。这种情况可以使用局部变量来解决:

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

【问题讨论】:

标签: javascript angular typescript rxjs arrow-functions


【解决方案1】:

这与 rx 或 Angular 无关,与 Javascript 和 Typescript 无关。

我假设您熟悉 Javascript 中函数调用上下文中 this 的语义(如果没有,则有 no shortage of explanations online)——这些语义当然适用于第一个 sn-p,那就是this.messagesubscribe()there 中未定义的唯一原因。那只是Javascript。

既然我们在谈论 Typescript: Arrow functions 是一个 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'
    });

你会得到预期的结果。

【讨论】:

  • 我知道这是一个老问题 - 但是当我按照你的回答并在 google chrome 中运行我的应用程序时,我遇到了页面崩溃 - 内存错误.. 有什么想法吗?
  • 在胖箭头函数中引用外部'this'有什么快速的解决方案吗?
  • @etlds,如果您在谈论在调试时引用“this”,那么您可以注意 _this 否则,在内部,“this”指的是外部上下文(在箭头函数中使用时)
  • 谢谢,这很有用!
【解决方案2】:

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

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

 ....

 const dataHandler = (location) => {
     ...
 }

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

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

 .subscribe(dataHandler, errorHandler);

这太简洁了!但是,如果需要上下文,那将无法正常工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多