ObservableChangeSet 等待列表准备好后再观看
ObservableChangeSet wait until list is ready before watching
我们有一个列表页面,我们可以在其中启用或禁用 [=29=]thing™ 使用 <switch />
That thing™ is使用 IsActive 标志切换
public class Thing
{
/* ... */
[Reactive] public bool IsActive { get; set; }
}
给定以下更改侦听器,想法是当 IsActive
属性 更改时(切换开关上的用户交互),我们调用 _saveItemCommand
来保存实体新 IsActiveState
.
public ObservableCollection<Thing> DataObjectList {get;} = new ObservableCollection<Thing>();
public MyClass()
{
_saveItemCommand = ReactiveCommand.CreateFromTask(SaveItemInternal);
_listWatcher = DataObjectList
.ToObservableChangeSet()
.AsObservableList()
.Connect()
.WhenPropertyChanged(x => x.IsActive)
.Throttle(TimeSpan.FromMilliseconds(250))
.ObserveOn(RxApp.MainThreadScheduler)
.Select(x => x.Sender)
.InvokeCommand(_saveItemCommand);
}
public void OnNavigatingTo()
{
var newItems = _myService.GetNewItems();
DataObjectList.AddRange(newItems);
}
public void OnDestroy()
{
_listWatcher?.Dispose();
}
我遇到的问题是,当我设置列表时,似乎在调用 AddRange
后立即对列表中的最后一项调用该命令。
我试过使用 .Skip(1)
但没有任何运气,但有一件似乎有效但很丑的事情是 .Skip(DataObjectList.Length)
我怎样才能做到直到用户第一次切换开关时才调用命令?设置此侦听器的正确方法是什么?
您很可能想要添加一个 Where
语句来指示它应该只在 IsActivated 开关上调用。
_listWatcher = DataObjectList
.ToObservableChangeSet()
.AsObservableList()
.Connect()
.WhenPropertyChanged(x => x.IsActive)
.Throttle(TimeSpan.FromMilliseconds(250))
.ToCollection()
.Where(x => x.Any(value => value.IsActive))
.ObserveOn(RxApp.MainThreadScheduler)
.Select(x => x.Sender)
.InvokeCommand(_saveItemCommand);
所以我添加的两行是
.ToCollection()
.Where(x => x.Any(value => value.IsActive))
ToCollection()
会将其转换为可观察列表,而 Where
会将您的可观察对象限制在 IsActive
值发生变化时。
如果您希望它只在 Where()
调用之后发生一次,您可能希望添加一个 FirstAsync()
调用。
在对 Glenn 的回答发表评论并与 Rodney 进行一些额外对话之后,这就是最终起作用的方法。
_listWatcher = DataObjectList
.ToObservableChangeSet()
.AsObservableList()
.Connect()
.WhenPropertyChanged(x => x.IsActive)
.Throttle(TimeSpan.FromMilliseconds(250))
.Skip(1)
.DistinctUntilChanged()
.ObserveOn(RxApp.MainThreadScheduler)
.Select(x => x.Sender)
.InvokeCommand(_createActivationsInternal);
我们有一个列表页面,我们可以在其中启用或禁用 [=29=]thing™ 使用 <switch />
That thing™ is使用 IsActive 标志切换
public class Thing
{
/* ... */
[Reactive] public bool IsActive { get; set; }
}
给定以下更改侦听器,想法是当 IsActive
属性 更改时(切换开关上的用户交互),我们调用 _saveItemCommand
来保存实体新 IsActiveState
.
public ObservableCollection<Thing> DataObjectList {get;} = new ObservableCollection<Thing>();
public MyClass()
{
_saveItemCommand = ReactiveCommand.CreateFromTask(SaveItemInternal);
_listWatcher = DataObjectList
.ToObservableChangeSet()
.AsObservableList()
.Connect()
.WhenPropertyChanged(x => x.IsActive)
.Throttle(TimeSpan.FromMilliseconds(250))
.ObserveOn(RxApp.MainThreadScheduler)
.Select(x => x.Sender)
.InvokeCommand(_saveItemCommand);
}
public void OnNavigatingTo()
{
var newItems = _myService.GetNewItems();
DataObjectList.AddRange(newItems);
}
public void OnDestroy()
{
_listWatcher?.Dispose();
}
我遇到的问题是,当我设置列表时,似乎在调用 AddRange
后立即对列表中的最后一项调用该命令。
我试过使用
.Skip(1)
但没有任何运气,但有一件似乎有效但很丑的事情是.Skip(DataObjectList.Length)
我怎样才能做到直到用户第一次切换开关时才调用命令?设置此侦听器的正确方法是什么?
您很可能想要添加一个 Where
语句来指示它应该只在 IsActivated 开关上调用。
_listWatcher = DataObjectList
.ToObservableChangeSet()
.AsObservableList()
.Connect()
.WhenPropertyChanged(x => x.IsActive)
.Throttle(TimeSpan.FromMilliseconds(250))
.ToCollection()
.Where(x => x.Any(value => value.IsActive))
.ObserveOn(RxApp.MainThreadScheduler)
.Select(x => x.Sender)
.InvokeCommand(_saveItemCommand);
所以我添加的两行是
.ToCollection()
.Where(x => x.Any(value => value.IsActive))
ToCollection()
会将其转换为可观察列表,而 Where
会将您的可观察对象限制在 IsActive
值发生变化时。
如果您希望它只在 Where()
调用之后发生一次,您可能希望添加一个 FirstAsync()
调用。
在对 Glenn 的回答发表评论并与 Rodney 进行一些额外对话之后,这就是最终起作用的方法。
_listWatcher = DataObjectList
.ToObservableChangeSet()
.AsObservableList()
.Connect()
.WhenPropertyChanged(x => x.IsActive)
.Throttle(TimeSpan.FromMilliseconds(250))
.Skip(1)
.DistinctUntilChanged()
.ObserveOn(RxApp.MainThreadScheduler)
.Select(x => x.Sender)
.InvokeCommand(_createActivationsInternal);