मैं एक एमवीवीएम ढांचे में आरएक्स का उपयोग करने में देख रहा हूं। यह विचार है कि दृश्य मॉडल में डेटा को प्रोजेक्ट करने के लिए इन-मेमोरी डेटासेट पर 'लाइव' LINQ क्वेरीज़ का उपयोग करना है।IObservable (Rx) का उपयोग INOTifyCollection के रूप में MVVM के लिए बदलें प्रतिस्थापन के रूप में?
पहले यह INotifyPropertyChanged/INotifyCollectionChanged और CLINQ नामक एक ओपन सोर्स लाइब्रेरी के उपयोग के साथ संभव हो गया है। आरएक्स और आईओब्सर्वेबल के साथ संभावित स्रोत स्रोतों के माध्यम से स्रोत मॉडल से बदलती घटनाओं को प्रसारित करने के लिए विषय वर्गों का उपयोग करके अधिक घोषणात्मक व्यू मॉडेल में जाना है। IOervervable से नियमित डाटाबेसिंग इंटरफेस में एक रूपांतरण अंतिम चरण के लिए आवश्यक होगा।
समस्या यह है कि आरएक्स अधिसूचना का समर्थन नहीं करता है कि धारा से एक इकाई को हटा दिया गया है। नीचे उदाहरण
कोड एक पीओसीओ दिखाता है जो क्षेत्र राज्य के लिए व्यवहारकर्ता वर्ग का उपयोग करता है। कोड इन इकाइयों का संग्रह बनाने के लिए चला जाता है और फ़िल्टर स्ट्रीम को एक साथ मर्ज करने के लिए कंसैट का उपयोग करता है। इसका मतलब है कि पीओसीओ में किए गए किसी भी बदलाव को एक ही स्ट्रीम में रिपोर्ट किया जाता है।
रेटिंग के लिए फ़िल्टर करने के लिए इस स्ट्रीम के लिए फ़िल्टर फ़िल्टर == 0 है। जब भी ऐसा होता है तो सब्सक्रिप्शन डिबग विंडो में परिणाम को आउटपुट करता है।
सेटिंग्स किसी भी तत्व पर रेटिंग = 0 घटना को ट्रिगर करेगा। लेकिन रेटिंग 5 पर वापस सेट करने से कोई घटना नहीं दिखाई देगी।
CLINQ के मामले में क्वेरी का आउटपुट INotifyCollectionChanged का समर्थन करेगा - ताकि क्वेरी परिणाम से जोड़े गए और हटाए गए आइटम सही परिणाम को इंगित कर सकें कि क्वेरी परिणाम बदल गया है (एक आइटम जोड़ा या हटाया गया है)।
एकमात्र तरीका यह है कि मैं इस पते के बारे में सोच सकता हूं, दो धाराओं को oppossite (दोहरी) क्वेरी के साथ सेट अप करना है। विपरीत धारा में जोड़ा गया एक आइटम परिणामसेट से हटाने का तात्पर्य है। यह विफल होने पर, मैं केवल FromEvent का उपयोग कर सकता हूं और किसी भी इकाई मॉडल को देखने योग्य नहीं बना सकता - जो आरएक्स को केवल एक ईवेंट एग्रीगेटर बनाता है। कोई संकेतक?
using System;
using System.ComponentModel;
using System.Linq;
using System.Collections.Generic;
namespace RxTest
{
public class TestEntity : Subject<TestEntity>, INotifyPropertyChanged
{
public IObservable<string> FileObservable { get; set; }
public IObservable<int> RatingObservable { get; set; }
public string File
{
get { return FileObservable.First(); }
set { (FileObservable as IObserver<string>).OnNext(value); }
}
public int Rating
{
get { return RatingObservable.First(); }
set { (RatingObservable as IObserver<int>).OnNext(value); }
}
public event PropertyChangedEventHandler PropertyChanged;
public TestEntity()
{
this.FileObservable = new BehaviorSubject<string>(string.Empty);
this.RatingObservable = new BehaviorSubject<int>(0);
this.FileObservable.Subscribe(f => { OnNotifyPropertyChanged("File"); });
this.RatingObservable.Subscribe(f => { OnNotifyPropertyChanged("Rating"); });
}
private void OnNotifyPropertyChanged(string property)
{
if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(property));
// update the class Observable
OnNext(this);
}
}
public class TestModel
{
private List<TestEntity> collection { get; set; }
private IDisposable sub;
public TestModel()
{
this.collection = new List<TestEntity>() {
new TestEntity() { File = "MySong.mp3", Rating = 5 },
new TestEntity() { File = "Heart.mp3", Rating = 5 },
new TestEntity() { File = "KarmaPolice.mp3", Rating = 5 }};
var observableCollection = Observable.Concat<TestEntity>(this.collection.Cast<IObservable<TestEntity>>());
var filteredCollection = from entity in observableCollection
where entity.Rating==0
select entity;
this.sub = filteredCollection.Subscribe(entity =>
{
System.Diagnostics.Debug.WriteLine("Added :" + entity.File);
}
);
this.collection[0].Rating = 0;
this.collection[0].Rating = 5;
}
};
}
"समस्या यह है कि आरएक्स सूचना है कि एक इकाई धारा से हटा दिया गया समर्थन करने के लिए प्रतीत नहीं होता है" - इस वजह से IObservable एक सतत् संग्रह, केवल मूल्यों का एक अतुल्यकालिक धारा का प्रतिनिधित्व नहीं करता। –