【发布时间】:2015-01-05 21:44:10
【问题描述】:
我将事件(来自按钮的分页事件)转换为 IObservable 并异步接收来自服务的结果。
作为副作用,我必须更新子视图。我有两个解决方案:
-
选择中的副作用:
//Converting events to a "stream" of search results. IObservable<SearchResult> resultsFromPageChange = Observable.FromEventPattern<EventArgs>(this, "PageChangedEvent") .Throttle(TimeSpan.FromMilliseconds(500)) .Select(async ev => { var input = new SearchResultInput() { PageSize = PageSize, PageIndex = PageIndex, SearchOptions = _currentSearchOptions, SearchText = SearchText.Value }; var result = await GetPagedComponents(input); //Side effect ActivateAttributesView(result.Components.FirstOrDefault()); return result; }).Switch(); //flatten and take most recent. -
在subsribe中做副作用:
//Converting events to a "stream" of search results. IObservable<SearchResult> resultsFromPageChange = Observable.FromEventPattern<EventArgs>(this, "PageChangedEvent") .Throttle(TimeSpan.FromMilliseconds(500)) .Select(async ev => { var input = new SearchResultInput() { PageSize = PageSize, PageIndex = PageIndex, SearchOptions = _currentSearchOptions, SearchText = SearchText.Value }; return await GetPagedComponents(input); }).Switch(); //flatten and take most recent. //Do side effect in the subscribe resultsFromPageChange.Subscribe(x => { if (x != null) ActivateAttributesView(x.Components.FirstOrDefault()); });
这两种方法都有效。我应该选择哪种解决方案?为什么?
谢谢。
因为有问题为什么这会产生值,所以这里是完整的代码:
//Converting events to a "stream" of search results.
IObservable<SearchResult> resultsFromPageChange = Observable.FromEventPattern<EventArgs>(this,
"PageChangedEvent")
.Throttle(TimeSpan.FromMilliseconds(500))
.Select(async ev =>
{
var input = new SearchResultInput()
{
PageSize = PageSize,
PageIndex = PageIndex,
SearchOptions = _currentSearchOptions,
SearchString = SearchString.Value
};
return await SearchComponentsPaged(input);
}).Switch(); //flatten and take most recent.
SearchString = new ReactiveProperty<string>(""); //Bound to TextBox.Text
//Create a "stream" of search results from a string given by user (SearchString)
SearchResult = SearchString
.SetValidateNotifyError(s => _componentDataService.ValidateSearchStringLength(s).Errors)
.Throttle(TimeSpan.FromMilliseconds(500))
.Select(async term =>
{
var input = new SearchResultInput()
{
PageSize = PageSize,
PageIndex = PageIndex,
SearchOptions = _currentSearchOptions,
SearchString = term
};
return await SearchComponentsPaged(input);
})
.Switch()
.Merge(resultsFromPageChange) //Merge the result of paging and text changing.
.ToReactiveProperty();
//Update Attributes view
SearchResult.Subscribe(searchResult =>
{
if (searchResult != null)
{
ActivateAttributesView(searchResult.Components.FirstOrDefault());
SearchResult.Value.TotalItemsCount = searchResult.TotalItemsCount;
}
});
它的实际作用是在搜索字符串更改时向数据库发送搜索请求并获取分页结果,或者在收到 PageChangedEvent 时获取具有相同搜索字符串的另一个页面。 .Merge(...) 是订阅吗?
【问题讨论】:
-
对于您的第一个解决方案,如果没有订阅,
ActivateAttributesView会被调用吗? -
嗯,我不知道“如果没有订阅”到底是什么意思。我所知道的是,对于解决方案 2,我必须明确检查是否为空。我不必使用解决方案 1 检查这一点。
-
-- 没关系,我没有意识到您正在使用基于
Task的Switch重载。 -
为什么一种解决方案有时会产生您必须防范的空值,而另一种则不会?此外,除非您订阅,否则解决方案 1 实际上不会做任何事情,即使您没有提供订阅回调(例如
.Switch().Subscribe()),这是因为FromEventPattern在您订阅之前实际上不会注册事件处理程序。 -
我不明白为什么会有空的结果。我不订阅它。但是我将这个“流”与另一个合并。那是订阅吗?我不知道。我将编辑示例以显示更多我的实际(工作)代码。
标签: c# system.reactive