当前位置: 首页 > 知识库问答 >
问题:

RxJS 5可观察和变量范围aka为什么我的变量不可读

步建茗
2023-03-14

TypeScript 1.9RxJS 5 beta 6编写的Angular 2 RC4应用程序

我真的很难理解为什么订阅时我的类变量没有传递给可观察的生成函数。下面是我的代码,但您可以看到它在这个插件上运行(请参见app/app.component.ts

//this is the problematic var. Can't pass its updated value to the Observable
input = 'nothing'; //<- default value

ngOnInit(){//<- this runs right after class constructor
    //set to the value we want to send to the server
    this.input = 'something';
}
start(){
    //to make sure input = something when we subscribe
    this.print("Subscribing when input = "+this.input);
    this.source.subscribe(d=>this.print(d));
}
//Simulate sending input to the server
source = this.queryServer(this.input)
    .do(()=>this.print('Emitting new value...'));

//server just returns what it received
queryServer(input){return Observable.from(['Server sees '+input])}

print(value){this.log.push(value);}
log=[];

通过调用start()

  • 当输入=某物时订阅
  • 发出新值…
  • 服务器什么也看不到

为什么当我们调用subscribe时,即使class属性是something,也不会将nothing传递给queryserver()?我试图使input成为一个对象,比如input={d:'something'}认为问题可能与传递值而不是引用有关,但结果是一样的。


共有2个答案

罗翰
2023-03-14

感谢@paulpdaniels提供的有用信息。他建议我在设置了input=something之后,在ngOnInit中编写源代码。这适用于input的第一个值,但实际上input将在ngOnInit完成后继续更改,因此将再次发出过时的数据。

真正让我惊讶的是,即使输入是一个对象(而不是一个简单的字符串),OP中的问题仍然存在。因为对象是通过JS中的引用分配的,所以我期望不同。

我选择的代码设计是在一个setter中为输入编写源代码。这样,每次设置该值时,source都会刷新:

source:Observable<any>;

_input = 'nothing';
get input(){return this._input;}
set input(val){
    this._input = val;
    source = this.queryServer(val)
        .do(()=>this.print('Emitting new value...'));
}

对我来说,仍然感觉像黑客,但我对可观察事物是全新的,所以也许没有更好的方法了。如果有,我希望有人能教我。

任飞龙
2023-03-14

发生这种情况是因为在构造组件时,您正在将输入的默认值传递给queryServer。即使您在ngInit中更改了它,它也已经被用于构建您随后订阅的管道。你基本上是在做以下事情:

this.input = "nothing";
const copyOfInput = this.input;
this.input = "something";
console.log(copyOfInput); //-> nothing

您已经更改了此所指向的内容。输入的所指向的内容,但您制作的副本仍指向旧值。我假设您实际上想要在ngInit中初始化管道,而不是作为对象构造的一部分。

 类似资料:
  • 本章介绍当模板在访问变量时发生了什么事情,还有变量是如何存储的。 当调用 Template.process 方法时,它会在方法内部创建一个 Environment 对象,在 process 返回之前一直使用。 该对象存储模板执行时的运行状态信息。除了这些,它还存储由模板中指令,如 assign, macro, local 或 global 创建的变量。 它不会尝试修改传递给 process 的数据

  • 问题内容: 我知道变量作用域由块的开始和块的结尾包围。如果在块内声明了相同的变量,则会发生编译错误。但是,请看以下示例。 在这里,可以在方法中重新声明,尽管它已经在类中声明了。但是在块中,无法重新声明。 为什么类范围变量的重新声明不产生错误,而方法范围变量的重新声明却产生错误? 问题答案: 这是因为不是变量,而是实例字段。允许局部变量与字段具有相同的名称。为了区分变量和具有相同名称的字段,我们在实

  • 问题内容: 我知道变量作用域由块的开始和块的结尾包围。如果在块内声明了相同的变量,则会发生编译错误。但是,请看以下示例。 在这里,可以在方法中重新声明,尽管它已经在类中声明了。但是在块中,无法重新声明。 为什么类范围变量的重新声明不产生错误,而方法范围变量的重新声明却产生错误? 问题答案: 这是因为不是变量,而是实例字段。允许局部变量与字段具有相同的名称。为了区分变量和具有相同名称的字段,我们在实

  • 问题内容: javascript中变量的范围是什么?它们在函数内部和外部的作用域是否相同?还是有关系吗?另外,如果变量是全局定义的,则将变量存储在哪里? 问题答案: TLDR JavaScript具有词汇(也称为静态)作用域和闭包。这意味着您可以通过查看源代码来确定标识符的范围。 四个范围是: 全球-一切可见 功能-在功能(及其子功能和块)中可见 块-在块(及其子块)中可见 模块-在模块内可见 在

  • 问题内容: 我想知道是否有什么办法可以在程序运行时观察变量值的变化。当然不使用调试器,我想以 编程方式进行 。例如: 因此,在运行时,如果在我的项目中任何类的任何方法中修改了此value 事件,则应调用该事件。 问题答案: 您需要用一个类替换该类型,该类将在值更改时调用您的侦听器。您可能想忽略未实际更改的值的设置。 例如 您可以使用字节码注入执行此替换,但是更改原始代码非常简单。 一种替代方法是监

  • 问题内容: 我有一类具有各种成员变量的类。有一个构造函数,有getter方法,但没有setter方法。实际上,该对象应该是不变的。 现在我注意到了以下几点:当我使用getter方法获得变量列表时,可以添加新值,依此类推- 可以更改。下次调用此变量时,将返回更改的内容。怎么会这样?我没有再设置它,我只是在做它!使用这种行为是不可能的。那么这里有什么区别? 问题答案: 仅仅因为 对 列表 的引用 是不