ReactiveUI:响应 属性 的变化
ReactiveUI: React to changes of a property
我正在使用 ReactiveUI 迈出第一步,但我无法获得一个非常基本的示例来工作。我想在 属性 "SearchTerm" 更改后立即执行任务。我按照 ReactiveUI ("a compelling example") 的 github 页面上的说明操作。
我有一个带有 属性 SearchTerm 的 ViewModel,它在我的视图中绑定到一个 TextBox。如果我更新 TextBox 的内容,属性 会按预期更新(我使用 UpdateSourceTrigger=PropertyChanged
)。
我的可观察对象中的代码从未触发:
public class MainWindowViewModel: ReactiveObject
{
public string SearchTerm
{
get { return m_SearchTerm; }
set { this.RaiseAndSetIfChanged(ref m_SearchTerm, value); }
}
private string m_SearchTerm;
public MainWindowViewModel()
{
SearchResults = new List<string>();
var canSearch = this.WhenAny(x => x.SearchTerm, x => !string.IsNullOrWhiteSpace(x.GetValue()));
var search = ReactiveCommand.CreateAsyncTask(canSearch,
async _ => {
// this is never called
return await dosearch(this.SearchTerm);
});
search.Subscribe(results => {
// this is never called too
SearchResults.Clear();
SearchResults.AddRange(results);
});
}
private async Task<List<string>> dosearch(string searchTerm)
{
await Task.Delay(1000);
return new List<string>() { "1", "2", "3" };
}
public List<string> SearchResults { get; private set; }
}
您的命令中的代码永远不会触发,因为您没有在任何地方调用该命令。您必须将您的命令绑定到任何事件(例如输入文本更改、按钮单击等)。
首先,公开您来自 ViewModel
的命令:
public ReactiveCommand<List<string>> Search { get; private set; }
接下来,在构造函数中赋值:
this.Search = ReactiveCommand.CreateAsyncTask(canSearch,
async _ => {
return await dosearch(this.SearchTerm);
});
最后,在输入更改时调用命令(这是您的代码中关键的缺失部分):
this.WhenAnyValue(x => x.SearchTerm)
.InvokeCommand(this, x => x.Search);
将上述代码放入构造函数中。
请注意,这将在用户键入时不断触发搜索。要解决此问题,您可以使用名为 Throttle
、as seen in the example you linked to.
的 Rx 运算符
我正在使用 ReactiveUI 迈出第一步,但我无法获得一个非常基本的示例来工作。我想在 属性 "SearchTerm" 更改后立即执行任务。我按照 ReactiveUI ("a compelling example") 的 github 页面上的说明操作。
我有一个带有 属性 SearchTerm 的 ViewModel,它在我的视图中绑定到一个 TextBox。如果我更新 TextBox 的内容,属性 会按预期更新(我使用 UpdateSourceTrigger=PropertyChanged
)。
我的可观察对象中的代码从未触发:
public class MainWindowViewModel: ReactiveObject
{
public string SearchTerm
{
get { return m_SearchTerm; }
set { this.RaiseAndSetIfChanged(ref m_SearchTerm, value); }
}
private string m_SearchTerm;
public MainWindowViewModel()
{
SearchResults = new List<string>();
var canSearch = this.WhenAny(x => x.SearchTerm, x => !string.IsNullOrWhiteSpace(x.GetValue()));
var search = ReactiveCommand.CreateAsyncTask(canSearch,
async _ => {
// this is never called
return await dosearch(this.SearchTerm);
});
search.Subscribe(results => {
// this is never called too
SearchResults.Clear();
SearchResults.AddRange(results);
});
}
private async Task<List<string>> dosearch(string searchTerm)
{
await Task.Delay(1000);
return new List<string>() { "1", "2", "3" };
}
public List<string> SearchResults { get; private set; }
}
您的命令中的代码永远不会触发,因为您没有在任何地方调用该命令。您必须将您的命令绑定到任何事件(例如输入文本更改、按钮单击等)。
首先,公开您来自 ViewModel
的命令:
public ReactiveCommand<List<string>> Search { get; private set; }
接下来,在构造函数中赋值:
this.Search = ReactiveCommand.CreateAsyncTask(canSearch,
async _ => {
return await dosearch(this.SearchTerm);
});
最后,在输入更改时调用命令(这是您的代码中关键的缺失部分):
this.WhenAnyValue(x => x.SearchTerm)
.InvokeCommand(this, x => x.Search);
将上述代码放入构造函数中。
请注意,这将在用户键入时不断触发搜索。要解决此问题,您可以使用名为 Throttle
、as seen in the example you linked to.