简体   繁体   English

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

[英]Access variables declared a component from a RxJS subscribe() function

I am able to use this.variable to access variables in any part of the component, except inside RxJS functions like subscribe() or catch() . 我可以使用this.variable来访问组件任何部分的变量,除了在诸如subscribe()catch()类的RxJS函数内。

In the example below, I want to print a message after running a process: 在下面的示例中,我想在运行进程后打印一条消息:

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

When I run doSomething() , I get undefined . 当我运行doSomething() ,我得到了未定义 This scenario can be solved using a local variable: 可以使用局部变量来解决此方案:

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

I suppose this is related to the this , however, why I can't access the this.message inside the subscribe() ? 我想这是关系到this ,可是,为什么我不能访问this.message内部subscribe()

This has nothing to do with rx or angular, and everything to do with Javascript and Typescript. 这与rx或angular无关,而与Javascript和Typescript有关。

I assume you're familiar with the semantics of this in the context of function invocations in Javascript (if not, there are no shortage of explanations online ) - those semantics apply in the first snippet, of course, and that's the only reason this.message is undefined inside subscribe() there. 我假设你熟悉的语义this函数的调用JavaScript中的情况下(如果没有,有没有解释短缺在线 ) -这些语义应用的第一个片段,当然,这是唯一的原因this.messagesubscribe()里面的this.message未定义。 That's just Javascript. 那只是Javascript。

Since we're talking about Typescript: Arrow functions are a Typescript construct intended (in part) to sidestep the awkwardness of these semantics by lexically capturing the meaning of this , meaning that this inside an arrow function === this from the outer context. 由于我们正在谈论的打字稿: 箭头功能是打字稿结构,旨在(部分)通过词法捕集的意义回避这些语义的尴尬this ,这意味着this里面的箭头功能=== this从外部环境。

So, if you replace: 所以,如果你更换:

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

by: 通过:

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

You'll get your expected result. 你会得到你期望的结果。

As an alternative to @drewmoore's answer, if you wish to have external functions you can do: 作为@ drewmoore答案的替代方案,如果您希望拥有外部功能,您可以:

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

 ....

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

By externalising the errorHandler function, it can be used in multiple places (ie. subscriptions). 通过外化errorHandler函数,它可以在多个地方使用(即订阅)。 By having as (fat) arrow functions your code will capture the 'this' context (as discussed in @Drewmoore's answer). 通过使用(胖)箭头函数,您的代码将捕获'this'上下文(如@Drewmoore的答案中所述)。

What is lacking is the ability to write the following and have handled like an arrow function. 缺少的是能够编写以下内容并像箭头函数一样处理。 The following works and passes the argument implicitly. 以下工作并隐式传递参数。 Unfortunately AFAIK you cannot capture the this context (perhaps use bind to achieve this, though that makes the code more verbose overall). 不幸的是AFAIK你无法捕获this上下文(也许使用bind来实现这一点,尽管这会让代码整体上更加冗长)。

 .subscribe(dataHandler, errorHandler);

This is soooo succinct! 这太简洁了! But alas won't work if the context is required. 但如果需要上下文,唉就行不通了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM