如何在 Angular 4 中推送到数组的 Observable? RxJS
Posted
技术标签:
【中文标题】如何在 Angular 4 中推送到数组的 Observable? RxJS【英文标题】:How to push to Observable of Array in Angular 4? RxJS 【发布时间】:2018-05-05 14:48:54 【问题描述】:我的服务类有一个属性:
articles: Observable<Article[]>;
它由使用标准http.get().map()
解决方案的getArticles() 函数填充。
如何手动将新文章推送到此数组中;一个尚未持久化,因此不是 http get 的一部分?
我的场景是,您创建了一篇新文章,在保存之前,我希望 Article[] 数组将这个新文章推送到它,以便它显示在我的文章列表中。
此外,该服务在 2 个组件之间共享,如果组件 A 使用 ng OnInit()
使用该服务并将结果绑定到重复部分 *ngFor
,将从组件 B 更新服务数组同时更新组件 A 的 ngFor
部分中的结果? 还是我必须手动更新视图?
非常感谢, 西蒙
【问题讨论】:
只是确认一下,简单来说,如何直接修改这个 Observable 包含的数组? 这是我可以使用主题的地方吗? 【参考方案1】:正如您在 cmets 中所说,我会使用主题。
保持articles
可观察而不是存储为数组的优点是http 需要时间,因此您可以订阅并等待结果。此外,这两个组件都会获得任何更新。
// Mock http
const http =
get: (url) => Rx.Observable.of(['article1', 'article2'])
const articles = new Rx.Subject();
const fetch = () =>
return http.get('myUrl').map(x => x).do(data => articles.next(data))
const add = (article) =>
articles.take(1).subscribe(current =>
current.push(article);
articles.next(current);
)
// Subscribe to
articles.subscribe(console.log)
// Action
fetch().subscribe(
add('article3')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.2/Rx.js"></script>
【讨论】:
由于articles
是一个 observable,组件订阅它(在 javascript 中)或直接在带有 async
过滤器的模板上使用它。因此,由于它们是通过响应式管道连接的,因此每当主题更新时它们都会自动更新。
注意,您可以根据组件进行订阅的时间来改变所使用的主题的类型。对于在 ngOnInit 或模板中订阅的组件,普通的主题可能很好,但如果它们在应用流程中订阅较晚(比如 ComponentB 在辅助页面上),您可能需要使用 @ 987654326@ 存储最后一个值并为新订阅“重播”它。
我倾向于将Subject
视为组件插入的插座,但它没有存储空间。 ReplaySubject
是一个带有(可配置)存储的套接字,BehaviorSubject
有一个项目的存储空间,但可以采用初始值 - 用于为组件提供一些默认值之前获取已填充它价值。
将此标记为完整,因为我可以看到这是正确答案。但是,我在我的应用程序中工作时遇到问题。您愿意继续与我讨论以尝试解决我遇到的问题吗?
当然可以。你想怎么做 - 你可以添加到问题中吗?【参考方案2】:
您可能只想存储文章数组,而不是存储整个 observable,例如
articles: Article[]
fetch()
this.get(url).map(...).subscribe(articles => this.articles)
然后您可以使用标准数组操作方法来操作articles
列表。
如果你存储 observable,它会在你每次订阅它时重新运行 http 调用(或使用| async
渲染它),这绝对不是你想要的。
但为了完整起见:如果您确实有一个要添加项目的数组的 Observable,您可以在其上使用 map 运算符向其中添加指定的项目,例如
observable.map(previousArray => previousArray.concat(itemtToBeAdded))
【讨论】:
【参考方案3】:来自 Angular 4 book ng-book
Subject<Array<String>> example = new Subject<Array<String>>();
push(newvalue:String):void
example.next((currentarray:String[]) : String[] =>
return currentarray.concat(newValue);
)
example.next 中的内容是获取存储在 observable 中的当前数组值,并在其上连接一个新值并将新数组值发送给订阅者。这是一个 lambda 表达式。我认为这仅适用于主题 observables,因为它们保留存储在其方法 subject.getValue(); 中的最后一个值;
【讨论】:
以上是关于如何在 Angular 4 中推送到数组的 Observable? RxJS的主要内容,如果未能解决你的问题,请参考以下文章