Javascript 可观察的与主体和可观察的

Javascript 可观察的与主体和可观察的,javascript,angular,typescript,rxjs,angular-services,Javascript,Angular,Typescript,Rxjs,Angular Services,我正在学习RxJs,我正在寻求对我的假设的确认或更正。 我试图使公共只读服务在我可以在服务类的各个位置使用的服务中可见。我想知道这样做是否正确: private myObservable = new Subject<T>(); public myObservable$: Observable<T> = this.myObservable.asObservable(); private myObservable=新主题(); public myObservable$:Ob

我正在学习RxJs,我正在寻求对我的假设的确认或更正。

我试图使公共只读服务在我可以在服务类的各个位置使用的服务中可见。我想知道这样做是否正确:

private myObservable = new Subject<T>();
public myObservable$: Observable<T> = this.myObservable.asObservable();
private myObservable=新主题();
public myObservable$:Observable=this.myObservable.asObservable();
  • 用户可以订阅
    myObservable$
  • 我可以使用
    myObservable.next(…)

它工作得很完美,但我有足够的经验,知道我可能只是一个无意中的白痴(RxJS是巨大的)。对于所述用例,这是正确的模式和正确的对象吗?

在项目中,我们使用这种观察对象,这给了您对私有观察对象的适当封装,但您仍然可以使用一些公共方法调用
next()

      private sourceName = new Subject<T>();
      name = this.sourceProductName.asObservable();

      sendName(item: T) {
        this.sourceName.next(item);
      }
private sourceName=新主题();
name=this.sourceProductName.asObservable();
发送名称(项目:T){
this.sourceName.next(项);
}

您所做的是正确的。不过,还有一个略短的符号。由于Subject已经是可观察的(它继承了可观察的类),因此可以将类型检查留给TypeScript:

private myObservable = new Subject<T>();
public myObservable$: Observable<T> = this.myObservable;
private myObservable=新主题();
public myObservable$:Observable=this.myObservable;
您服务的任何使用者都可以订阅
myObservable$
,但不能调用
myObservable$.next()
,因为TypeScript不允许您这样做(Observable类没有任何
next()
方法)

实际上,这是推荐的方法,RxJS内部从不使用
asObservable
。有关更详细的讨论,请参阅:


请参阅一个非常类似的问题:

您使用了BehaviorSubject,在我的用例中我不需要它。并添加了一个公共方法,从而否定了广播的封装。我不在乎你可以用
Subject
替换它,我有时用
getValue()
在某个时间段内检索此可观察值,它将满足你的需要。抱歉,我编辑了初始值并将其保留在那里,
Subject
不需要它。您直接复制了我的代码,然后通过向私有变量添加公共方法访问器来删除封装来破坏它。我想你可能误解了这个问题。如果您阅读代码,则可以将其替换为
name=new Subject()好吧,除了
next()
,你确实保护了一切,基于此,我认为你误读了我的帖子。我认为这归结为:我在OP中的假设是正确的。但是谢谢你帮我捅了捅。@EddieMarinaro没有通过
private
隐私这样的东西,所以这很难打破。我同意简单地包装这个方法是没有意义的。
asObservable
的要点是隐藏主题,但这是另一种隐藏方式。正确的第二行是
myObservable$=myObservable.asObservable()
完全没有
next
方法,并且也是
可观察的类型
可观察的类型由TypeScript强制执行。唯一可以避免这种情况的方法是使用
(myObservable$as any).next()
,而这通常是你永远不会做的。阅读两个GitHub链接,了解为什么RxJS内部总是使用这种方式。那么为什么它们提供
asObservable
。这是一种软弱的方法。好吧,这有点苛刻,但这是一种虚假的安全感。问题是人们往往忘记类型断言不是类型转换,因为它们看起来像类型转换。无论如何,RX Js的人都支持你,尽管其中一人非常不同意。如果你真的担心安全问题,我还建议你使用getter来接收可观察的
。否则,有人可能会用自己的
主题
覆盖它,并开始推送不需要的数据。是的,这是一种常见且正确的模式。但在许多情况下,这是不必要的。只有在需要向未绑定的组件发送通知时,才真正需要一个主题。如果您是绑定的,Angular的更改检测可以处理通知。我有一个例子,主题/行为主题和匹配的代码具有相同的功能,这里没有它:(MH-Take4和MH-Take5)@DeborahK基于对这个帖子中一些回复的一些评论,我很好奇你对在TypeScript中使用private有什么想法。难道一个人不应该使用private编写代码,因为它实际上不是private,难道一个人应该像编写C#一样使用typescript编写代码,而忽略transfile对私有和公共都一视同仁的事实吗?typescript的全部目的是通过给我们类型、接口、,和可访问性关键字(如
private
)。如果我们不打算使用这些东西。。。使用TypeScript是没有意义的。事实上,所有这些都被传开了并不重要。在某一点上,它都变成了1和0。:-)你说得对。TypeScript提供了更高的开发时间抽象。。。typescript的目的,正如其设计者所说,是提供JavaScript隐式类型系统的静态可验证形式化。切题地说,虽然程序员使用各种框架,希望假装它描述了一个类似Java的类型系统,但这个错误在Angular社区中是最常见的。长期以来,许多开发人员都不愿意学习JavaScript,认为TypeScript提供了JavaScript的替代品是严重错误的。以你在JS的背景,以及作为教育者的角色,你无疑意识到了这一点。