[英]Observable | Subscribe to get only the changed objects
我有一个使用C#Firebase中的包装器从Realtime-Database(Firebase)获取的对象列表。
private List<Job> jobList = null;
首先使用以下代码加载应用程序:
private async void PopulateList()
{
IReadOnlyCollection<Firebase.Xamarin.Database.FirebaseObject<Job>> items = await firebase
.Child("jobs")
.OnceAsync<Job>();
jobList = new List<Job>();
foreach (var item in items)
{
jobList.Add(
new Job
{
ID = item.Object.ID,
StartDate = item.Object.StartDate,
EndDate = item.Object.EndDate,
Description = item.Object.Description
});
}
SubscribeDbChanges();
}
我想订阅数据库以触发一个事件,然后将新对象更改/添加到列表中,并触发一个事件后记以显示或通知用户一次,即发生了更改。 为此,我通过以下方式将Observable即Reactive Rx.Net与All结合使用 :
private void SubscribeDbChanges()
{
Observable.All<FirebaseEvent<Job>>(
firebase
.Child("jobs")
.AsObservable<Job>(),
job => !jobList
.Contains(job.Object))
.Subscribe(jobItem =>
{
});
}
代码有什么问题吗? 此外,我应该在哪里创建更改已到达的事件?
首先,我建议您删除foreach/Add
,这是Select
的工作
private async void PopulateList()
{
jobList = (await firebase
.Child("jobs")
.OnceAsync<Job>())
.Select(item =>
new Job
{
ID = item.Object.ID,
StartDate = item.Object.StartDate,
EndDate = item.Object.EndDate,
Description = item.Object.Description
});
SubscribeDbChanges();
}
然后,我将使用Where
。 All
使用方式很奇怪,它是一种扩展方法,并且您像通常的静态方法一样调用它。 有可能,但是现在应该使用它。 这是Where
的代码:
private void SubscribeDbChanges()
{
firebase
.Child("jobs")
.AsObservable<Job>()
.Where(job => !jobList.Contains(job.Object))
.Subscribe(jobItem =>
{
});
}
感谢@Alexey Zimarev给我一个快速的单击,然后出现了如下代码:首先,首先使用ConcurrentDictionary作为数据成员并初始化Firebaseclient,然后填充列表;
FirebaseClient firebase;
private ConcurrentDictionary<string, Job> jobList ;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
firebase = new FirebaseClient("https://samplehosting-XXXX.firebaseio.com/");
PopulateList();
}
在此函数中,我初始化了字典并完成了UI工作,最后分别设置了侦听器以监视SubscribeToDbChanges中的更改
private async void PopulateList()
{
IReadOnlyCollection<Firebase.Xamarin.Database.FirebaseObject<Job>> items = await firebase
.Child("jobs")
.OnceAsync<Job>();
jobList = new ConcurrentDictionary<string, Job>();
foreach (var job in items)
{
while (!jobList.TryAdd(job.Object.ID, job.Object)) ;
}
list = FindViewById<ListView>(Resource.Id.listJobs);
list.ChoiceMode = ChoiceMode.Single;
HomeScreenAdapter ListAdapter = new HomeScreenAdapter(this, jobList);
list.Adapter = ListAdapter;
SubscribeToDbChanges();
}
在这里,我设置插入观察员所不具备的字典和比设置是在字典中可用的密钥 删除观察者的键 。
private void SubscribeToDbChanges()
{
firebase
.Child("jobs").AsObservable<Job>()
.Where(job => !jobList.ContainsKey(job.Object.ID) && job.EventType == Firebase.Xamarin.Database.Streaming.FirebaseEventType.InsertOrUpdate)
.Subscribe(job =>
{
if (job.EventType == Firebase.Xamarin.Database.Streaming.FirebaseEventType.InsertOrUpdate)
{
while (!jobList.TryAdd(job.Object.ID, job.Object)) ;
}
});
firebase
.Child("jobs").AsObservable<Job>()
.Where(job => jobList.ContainsKey(job.Object.ID) && job.EventType == Firebase.Xamarin.Database.Streaming.FirebaseEventType.Delete)
.Subscribe(job =>
{
Thread remove = new Thread(() =>
{
Job removed = null;
jobList.TryRemove(job.Object.ID, out removed);
});
remove.Start();
});
}
PS:假设在这里,我假设由于存在内存,因此无法比较在上述问答中添加的对象。 就像实例化一个新对象一样,它可能与列表中已经存在的克隆不同。 如果我对Linq行为有误,请纠正我。 但是上面给出的代码在我的字典中适用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.