我的情况:我有一个数据存储区,在那里我可以获得可以使用RxJS Observables观察到的模型。一般类型签名是
const foo = new Model({id: 123}, dataStore);
foo.asObservable().subscribe((v) => /* do stuff with values of this model */ );
一般的概念是,像observables这样的数据处理有两个方面的帮助:(a)当你有一个冷缓存情况时(比如浏览器的localStorage有一些过时的数据)但仍想显示某些东西正在获取实际数据,以及(b)当您已经加载了正确的数据时,无论是在本地还是在需要传播的后端进行更改。到目前为止,这种方法运作良好。
下一个问题是模型与其他模型有关系(例如,父母有很多孩子)。按照惯例,我可以做像
这样的事情foo.asObservable().subscribe(v => console.log(v.relationships.children))
和(在这里忽略空错误),我最初得到[1,2,3],然后在父子关系中添加4时得到[1,2,3,4]。和我一起到目前为止?
问题是我经常想要访问这些孩子,而不是作为索引,而是作为可观察的模型(因此我可以显示用户社区的所有成员的名字,例如,两者都是社区和所有成员都是数据模型)。我目前正在使用我的控制器代码中的大量样板文件执行此操作,涉及对.combineLatest
的大量调用。
我想要做的是为这种类型的对象定义一个自定义操作符,这样我就可以将它们整合在一起。理想情况下它看起来像:
foo.asObservable().inflateRelationship('members').subscribe(
(v) => // v === [{name: 'steve'}, {name: 'gertude'} ...] etc
);
我实际上这部分工作,但问题是开始实际链。我正在关注instructions for extending Observable,创建一个实现lift
的新CustomObservable类,但我的问题是我不能在这里使用静态Observable方法,比如Observable.merge()来生成我的初始值在Model.asObservable
中可观察到。
我的问题来了:
const preload$ = Observable...
// create the "load from cache and backend observable"
const update$ = Observable ...
// create the "update after load when the storage updates observable"
return new CustomObservable(context).merge(preload$, update$);
这是失败的最后一行。我想在两个常规可观察流上返回由合并运算符生成的CustomObservable。我需要在那里向构造函数添加上下文,因为该上下文包含对实际膨胀子模型所需的数据存储的引用(没有它,id数组流是没有意义的。)
这就是我的具体问题:我创建了一个Observable运算符,我想将它作为一个类添加到CustomObservable中,所以我可以像普通的那样使用下游运算符,但我似乎无法正确获取整个链拉开了序幕。
任何指针,即使是正确(和非平凡)扩展Observable类的现有项目也是受欢迎的。我试着深入挖掘源代码,但我甚至无法想出那部分内容(看起来Observable类静态在其他地方被添加了,而且乍一看是多么不清楚,因为{{3}中没有定义})。
答案 0 :(得分:4)
这是其中之一"写一个很长的问题来叠加溢出并在你发布它之后不久找出答案"有点情况,但我想我只是为了后人而写出答案。
假设您已按照说明操作子类操作员,您所做的就是
asObservable() {
// do a bunch of stuff making different things
return Observable.merge(one$, two$)
.let(obs => new CustomObservable(context, obs);
然后在CustomObservable中你有
class CustomObservable extends Observable {
constructor(context, source) {
super();
this.source = source;
}
customOperator() {}
lift(operator) {
const obs = new CustomObservable(context, this);
obs.operator = operator;
return obs;
}
}
这让我做
Model.asObservable()
.filter() // normal RxJs operator here
.customOperator() // yay
.map() // back to other RxJs operators
.subscribe(v => console.log(v)) // or whatever
所以,是的。现在我的角度模型可以看起来更多。