Dynamic Data – Observable Cache – Transformative Operators

Bài viết về các operator trong phần Transformative Operators của Observable Cache.

AsObservableCache
  • Chuyển đổi một observable change set sang observable cache chỉ đọc/ ẩn các phương thức edit của source cache.
    (Object Browser: Converts the source to an read-only observable cache)
  • Giá trị trả về: có kiểu giống với source, để nối các operator tiếp theo.
  • Dạng cụ thể:
    IObservableCache<TObject, TKey> AsObservableCache<TObject, TKey>(this IObservableCache<TObject, TKey> source)
    

    hoặc

    IObservable<IChangeSet<TObject, TKey>> AsObservableCache<TObject, TKey>(this IObservable<IChangeSet<TObject, TKey>> source)
    
  • Ví dụ:
    var p8 = peopleSource.AsObservableCache();
    

    hoặc

    var p7 = peopleSource.Connect().Top(Comparer<Person>.Default, 20).AsObservableCache();
    
Convert (Obsolete) – Không dùng phương thức này nữa mà chuyển qua Transform
  • Chuyển đổi một object dựa vào value selector. Đây là một phiên bản tương tự nhưng nhẹ hơn Transform của Rx.NET, được sử dụng cho các non-disposable object.
    (Object Browser: Convert the object using the specified conversion function. This is a lighter equivalent of Transform and is designed to be used with non-disposable objects)
  • Giá trị trả về: Một Observable<IChangeSet> có thể khác kiểu dữ ban đầu dùng để nối các operator khác.
  • Dạng đầy đủ:
    IObservable<IChangeSet<TDestination, TKey>> Convert<TObject, TKey>(this IObservable<IChangeSet<TObject, TKey>> source, Func<TObject, TKey> conversionFactory)
    
  • Ví dụ:
    var p9 = peopleSource.Connect().Convert(p => new { p.Id, p.Name }).AsObservableCache();
    
DistinctValues
  • Lựa chọn các giá trị duy nhất từ source.
    (Object Browser: Selects distinct values from the source.)
  • Giá trị trả về: Trả về một change set các giá trị duy nhất được chỉ rõ bởi value selector (một Observable<IDistinctChangeSet>, không là observable cache nữa).
  • Dạng đầy đủ:
    IObservable<IDistinctChangeSet<TValue>> DistinctValues<TObject, TKey, TValue>(this IObservable<IChangeSet<TObject, TKey>> source, Func<TObject, TValue> valueSelector)
    
  • Ví dụ:
    //distinct observable of customers
    var customers = shared.DistinctValues(trade => trade.Customer);
    
Group
  • Tương tự operator GroupBy của Rx.NET, dùng để gom nhóm dữ liệu dựa trên một group selector.
    (Object Browser: Groups the source on the value returned by group selector factory. A group is included for each item in the resulting group source.)
  • Giá trị trả về: Trả về một observable IGroupChangeSet. Các item trong IGroupChangeSet<TObject, TKey, TGroupKey> là các IGroup<TObject, TKey, TGroupKey>, IGroup có thuộc tính Cache để lấy source.
  • Dạng đầy đủ:
    IObservable<IGroupChangeSet<TObject, TKey, TGroupKey>> Group<TObject, TKey, TGroupKey>(this IObservable<IChangeSet<TObject, TKey>> source, Func<TObject, TGroupKey> groupSelectorKey)
    

    hoặc

    IObservable<IGroupChangeSet<TObject, TKey, TGroupKey>> Group<TObject, TKey, TGroupKey>(this IObservable<IChangeSet<TObject, TKey>> source, Func<TObject, TGroupKey> groupSelectorKey, IObservable<IDistinctChangeSet<TGroupKey>> resultGroupSource)
    //(trong đó: resultGroupSource: A distinct stream used to determine the result)
    
  • Ví dụ:
    _job = tradeService.All
    .Connect(trade => trade.Status == TradeStatus.Live)
    .Group(trade => trade.CurrencyPair)
    .SubscribeMany(groupedData =>
    {
    var locker = new object();
    decimal latestPrice = 0;//subscribe to price and update trades with the latest price
    var priceHasChanged = marketDataService.Watch(groupedData.Key)
    .Synchronize(locker)
    .Subscribe(price =>
    {
    latestPrice = price.Bid;
    UpdateTradesWithPrice(groupedData.Cache.Items, latestPrice);
    });//connect to data changes and update with the latest price
    var dataHasChanged = groupedData.Cache.Connect()
    .WhereReasonsAre(ChangeReason.Add, ChangeReason.Update)
    .Synchronize(locker)
    .Subscribe(changes => UpdateTradesWithPrice(changes.Select(change => change.Current), latestPrice));
    
    return new CompositeDisposable(priceHasChanged, dataHasChanged);
    
    })
    .Subscribe();
    

    hoặc
    Cái overload thứ 2 chưa hiểu lắm.

QueryWhenChanged
  • Trả về toàn bộ underlying data với giá trị mới nhất để thực hiện truy vấn (truy vấn đối với underlying data đó mỗi khi nó thay đổi).
    (Object Browser: The latest copy of the cache is exposed for querying after each modification to the underlying data.)
  • Giá trị trả về: Trả về observable phát ra các giá trị được truy vấn.
  • Dạng đầy đủ:
    IObservable<TDestination> QueryWhenChanged<TObject, TKey, TDestination>(this IObservable<IChangeSet<TObject, TKey>> source, Func<IQuery<TObject, TKey>, TDestination> resultSelector)
    //(trong đó IQuery tương tự một collection, gồm các phương thức để truy vấn, điển hình là phương thức Lookup(TKey))
    
  • Ví dụ:
    //Build a message from selected items
    _deleteItemsText = selectedItems.QueryWhenChanged(query =>
    {
    if (query.Count == 0) return "Select log entries to delete";
    if (query.Count == 1) return "Delete selected log entry?";
    return $"Delete {query.Count} log entries?";
    })
    .ToProperty(this, viewmodel => viewmodel.DeleteItemsText, "Select log entries to delete");
    
RemoveKey
  • Loại bỏ key ra khỏi các thay đổi. Operator này làm cho cache change set chuyển thành list change set.
    (Object Browser: Removes the key which enables all observable list features of dynamic data)
  • Giá trị trả về: một Observable<IChangeSet<TObject>> (có thể thấy đã bị loại bỏ key) để nối các truy vấn tiếp theo. Ngoài ra còn một overload trả về void áp dụng cho ISourceCache.
  • Dạng đầy đủ:
    IObservable<IChangSet<TObject>> RemoveKey<TObject, TKey>(this IObservable<IChangeSet<TObject, TKey>> source)
    
  • Ví dụ:
    IObservable<IChangeSet<Person>> p10 = peopleSource.Connect().RemoveKey();
    
Sort
  • Sắp xếp sử dụng comparer (comparer này tương tự như operator Top). Lưu ý là có một overload cho phép thay đổi comparer thông qua observable.
    (Object Browser: Sorts a sequence as, using the comparer observable to determine the order.)
  • Giá trị trả về: Trả về một change set để có thể nối các operator tiếp theo.
  • Các dạng cụ thể:
    IObservable<ISortedChangeSet<TObject, TKey>> Sort<TObject, TKey>(this IObservable<IChangeSet<TObject, TKey>> source, IComparer<TObject> comparer)
    

    hoặc

    IObservable<ISortedChangeSet<TObject, TKey>> Sort<TObject, TKey>(this IObservable<IChangeSet<TObject, TKey>> source, IObservable<IComparer<TObject>> comparerObservable)
    
  • Ví dụ:
    IObservable<ISortedChangeSet<Person, int>> p11 = peopleSource.Connect().Sort(Comparer<Person>.Default);
    

    hoặc

    var sortController = new SortController<TradeProxy>();
    //(SortController tự tạo)var loader = tradeService.All.Connect()
    .Transform(trade => new TradeProxy(trade), new ParallelisationOptions(ParallelType.Ordered, 5))
    .Sort(sortContoller, SortOptimisations.ComparesImmutableValuesOnly)
    .Page(pageController) // this applies the paging and returns on result effecting the current page
    .ObserveOn(schedulerProvider.MainThread)
    //ensure page parameters class knows which page we are on
    .Do(changes => _pageParameters.Update(changes.Response))
    .Bind(_data) // update observable collection bindings
    .DisposeMany() //dispose when no longer required
    .Subscribe();
    
    var sortChange = SortParameters.ObservePropertyValue(t => t.SelectedItem).Select(prop => prop.Value.Comparer)
    .ObserveOn(schedulerProvider.TaskPool)
    //Change the sort controller
    .Subscribe(sortContoller.Change);
    
ToCollection
  • Chuyển đổi một change set sang kiểu collection. Mỗi sự thay đổi ở data source thì sẽ tạo ra một collection mới.
    (Object Browser: Converts the changeset into a fully formed collection. Each change in the source results in a new collection.)
  • Giá trị trả về: một observable phát ra các read-only collection cho mỗi sự thay đổi.
  • Dạng đầy đủ:
    IObservable<Generic.IReadOnlyCollection<TObject>> ToCollection<TObject, TKey>(this IObservable<IChangeSet<TObject, TKey>> source)
    
  • Ví dụ:
    IObservable<IReadOnlyCollection<Person>> p11 = peopleSource.Connect().ToCollection();
    
Transform
  • Tương tự Select trong Rx.NET.
    (Object Browser: Projects each update item to a new form using the specified transform function.)
  • Giá trị trả về: Một observable phát ra các changeset chứa kiểu dữ liệu đã được chuyển đổi.
  • Dạng đầy đủ:
    IObservable<IChangeSet<TDestination, TKey>> Transform<TDestination, TSource, TKey>(this IObservable<TObject, TKey> source, Func<TSource, TDestination> tranformFactory)
    và một số overload khác.
    
  • Ví dụ:
    cleanUp = group.Cache.Connect()
    .Transform(trade => new TradeProxy(trade))
    .Sort(SortExpressionComparer<TradeProxy>.Descending(p => p.Timestamp))
    .ObserveOn(schedulerProvider.MainThread)
    .Bind(Data)
    .DisposeMany()
    .Subscribe(_ => { }, ex => logger.Error(ex, "Error in TradesByPercentDiff"));
    
TransformMany
  • Tương tự như many transform (theo mình thì giống SelectMany hơn). Có 3 overload nhưng chủ yếu là thay đổi kiểu trả về của manySelector trong các dạng collection.
    (Object Browser: Equivalent to a select many transform. To work, the key must individually identify each child.)
  • Giá trị trả về: trả về một observable chứa các item trong collection được tạo ra bởi manySelector.
  • Dạng đầy đủ:
    IObservable<IChangeSet<TDestination, TDestinationKey>> TransformMany<TSource, TSourceKey, TDestination, TDestinationKey>(this IObservable<IChangeSet<TSource, TSourceKey>> source, Func<TSource, IEnumerable<TDestination>> manySelector, Func<TDestination, TDestinationKey> keySelector)
    
  • Ví dụ: (Phần ví dụ này các bạn xem Rx.NET SelectMany để hiểu rõ hơn về công dụng của TransformMany nhé)
    var p12 = peopleSource.Connect().TransformMany(p => GetPeopleProxyEnumerable(p), pp => pp.Id)
    .AsObservableCache();
    
TransformSafe
  • Có tác dụng tương tự Transform, đồng thời cung cấp một tham số truyền vào một action để xử lý lỗi mà không dừng stream.
    (Object Browser: Projects each update item to a new form using the specified transform function, providing an error handling action to safely handle transform errors without killing the stream.)
  • Giá trị trả về: tương tự khi dùng Transform
  • Các dạng đầy đủ:
    IObservable<IChangeSet<TDestination, TKey>> TransformSafe<TDestination, TSource, TKey>(this IObservable<IChangeSet<TSource, TKey>> source, Func<TSource, TDestination> transformFactory, Action<DynamicData.Kernel.Error> errorHandler)
    
  • Ví dụ:
TransformToTree
  • Chuyển một source cache thành một cây phân cấp, thường sử dụng trong TreeView.
    (Object Browser: Transforms the object to a fully recursive tree, create a hierarchy based on the pivot function.)
  • Giá trị trả về: Trả về một observable phát ra các IChangeSet chứa các Node.
  • Dạng đầy đủ:
    IObservable<IChangeSet<Node<TObject, TKey>, TKey>> TransformToTree<TObject, TKey>(this IObservable<IChangeSet<TObject, TKey>> source, Func<TObject, TKey> pivotOn)
    
  • Ví dụ: Xem đầy đủ về cách sử dụng ở đây:  REACTIVE TREE USING DYNAMIC DATA
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.