2017-01-22 46 views
1

我有我從Realtime-Database (Firebase)得到一個wrapper in C# Firebase.XamarinObservable |訂閱只得到改變的對象

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(); 
} 

我想訂閱數據庫來觸發一個事件,並將新的對象更改/添加到列表中,並在後續事件中觸發事件顯示或通知用戶一次,發生更改。爲此我使用的是可觀察即Reactive Rx.Net with All 以下列方式:

private void SubscribeDbChanges() 
{ 
    Observable.All<FirebaseEvent<Job>>(
      firebase 
       .Child("jobs") 
       .AsObservable<Job>(), 
      job => !jobList 
       .Contains(job.Object)) 
      .Subscribe(jobItem => 
       { 
       }); 
} 

有沒有一點毛病的代碼?而且,我應該在哪裏創建變更已到達的事件?

回答

1

感謝@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行爲有錯,請糾正我。然而,上面給出的代碼適用於我的字典場景。

3

首先,我會建議擺脫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 => 
      { 
      }); 
} 
+0

先生;在這裏要提到的是,OnceAsync將得到一個IReadOnlyCollection類型的對象,它不會讓我這樣做Select,那麼就可以調用GetEnumerator()。 – Technacron

+0

'IReadOnlyCollection'實現'IEnumerable'。你不看「選擇」的原因是你在「任務」上查找它。我更新了代碼,它確實包含了這個錯誤。但它不會改變可觀察的代碼。 –

+0

謝謝你的答覆先生,是的,我發現包括系統後。linq liabrary它的廣告功能。但仍然無法獲得我期待的適當結果。我設法寫了一個代碼給我預期的結果讓我分享答案 – Technacron