繁体   English   中英

可观察 订阅仅获取更改的对象

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM