第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

使用 WhenAnyObservable 組合和過濾多個(gè)事件

使用 WhenAnyObservable 組合和過濾多個(gè)事件

C#
哈士奇WWW 2021-11-07 19:24:02
我有一個(gè) ViewModel:一個(gè)列表 ReactiveList<MyObject>單個(gè) MyObjectIsBusy 布爾值當(dāng) MyObject 列表或單個(gè) MyObject 中的“Active”屬性都不為真或在任何情況下 IsBusy 為真時(shí),我想禁用該命令。在將 IsBusy 添加到圖片之前,我想出的最佳解決方案是:var canSave = this.WhenAnyObservable(    x => x.MyObjectsList.ItemChanged, x => x.MyObject.Changed)    .Where(x => x.PropertyName == "Active")    .Select(_ => MyObjectsList.Any(x => x.Active) || MyObject.Active);SaveCommand = ReactiveCommand.Create(Save, canSave);這個(gè)想法是每次 Active 屬性更改時(shí)都會(huì)重新評(píng)估。不確定這是否是最好的解決方案(因此歡迎任何改進(jìn)它的建議),但我絕對(duì)無法將 IsBusy 添加到圖片中,以便在 IsBusy 時(shí)重新評(píng)估 Select 子句(包括 IsBusy 狀態(tài))變化。
查看完整描述

2 回答

?
回首憶惘然

TA貢獻(xiàn)1847條經(jīng)驗(yàn) 獲得超11個(gè)贊

我認(rèn)為您的答案可以簡化。


var itemChangedObs = this.WhenAnyValue(x => x.MyObject.Active);

var isBusyObs = this.WhenAnyValue(x => x.IsBusy);

var listItemChangedObs = this.WhenAnyObservable(x => x.MyObectsList.ItemChanged).Where(x => x.PropertyName == "Active").Select(_ => MyObjectsList.Any(x => x.Active)).StartsWith(false)

var canRunCommand = itemChangedObs.CombineLatest(listItemChangedObs, isBusyObs, (itemActive, listItemActive, isBusy) => (itemActive || listItemActive) && !isBusy);

這個(gè)版本本質(zhì)上使用了一個(gè) CombineLatest ,它在將兩個(gè) observable 組合在一起后采用您想要的值的 Lambda。


在兩個(gè) Observables 都發(fā)出一個(gè)值之前,CombineLatest() 不會(huì)產(chǎn)生值,因此為什么 listItemChanged 在前面有一個(gè) StartsWith(false)。


默認(rèn)情況下,WhenAnyValue() 將始終發(fā)出值的 default(T) 作為其初始值,因此您不需要這些語句的 StartsWith。


查看完整回答
反對(duì) 回復(fù) 2021-11-07
?
慕妹3242003

TA貢獻(xiàn)1824條經(jīng)驗(yàn) 獲得超6個(gè)贊

這是另一種替代方法,它避免了對(duì)復(fù)雜度為 O(n) 的 MyObjectList.Any() 的需要。此解決方案涉及更多,但具有提高效率的潛力。除了計(jì)算listItemChangedObs observable的方式外,它與 Glenn 的CombineLatest方法相同。此版本保持列表中活動(dòng)對(duì)象數(shù)的運(yùn)行總數(shù)。因此,每次觸發(fā) ItemChanged 時(shí),它只需執(zhí)行 +1 或 -1 操作。然后它只檢查它是否大于 0。


public MyViewModel()

{

    var itemChangedObs = this.WhenAnyValue(x => x.MyObject.Active);

    var isBusyObs = this.WhenAnyValue(x => x.IsBusy);


    // Recalculate the # of active objects each time ObjectList is reassigned.

    var activeListItemCountInitializedObs = this

        .WhenAnyValue(x => x.ObjectList)

        .Select(

            list =>

            {

                // Return 0 if ObjectList is null.

                return list == null ? Observable.Return(0) : list

                    .ToObservable()

                    // Otherwise, increment by 1 for each active object.

                    .Select(x => x.Active ? 1 : 0)

                    // We use Aggregate, which is a single value sequence, because

                    // we're only interested in the final result.

                    .Aggregate((acc, current) => acc + current);

            })

        // We no longer need the inner observable from the last time active item count

        // was initialized. So unsubscribe from that one and subscribe to this most recent one.

        .Switch();


    var activeListItemCountChangedObs = this

        .WhenAnyObservable(x => x.ObjectList.ItemChanged)

        .Where(x => x.PropertyName == "Active")

        // Increment or decrement the number of active objects in the list.

        .Select(x => x.Sender.Active ? 1 : -1);


    // An IObservable<bool> that signals if *any* of objects in the list are active.

    var anyListItemsActiveObs = activeListItemCountInitializedObs

        .Select(

            // Use the initialized count as the starting value for the Scan accumulator.

            initialActiveCount =>

            {

                return activeListItemCountChangedObs

                    .Scan(initialActiveCount, (acc, current) => acc + current)

                    // Return true if one or more items are active.

                    .Select(x => x > 0)

                    .StartWith(initialActiveCount > 0);

            })

        // ObjectList was completely reassigned, so the previous Scan accumulator is

        // no longer valid. So we "reset" it by "switching" to the new one.

        .Switch();


    var canRunCommand = itemChangedObs

        .CombineLatest(

            anyListItemsActiveObs,

            isBusyObs,

            (itemActive, listItemActive, isBusy) => (itemActive || listItemActive) && !isBusy);


    Save = ReactiveCommand.CreateFromObservable(() => Observable.Return(Unit.Default), canRunCommand);

}

這是我運(yùn)行代碼時(shí)通過的單元測試。它基本上檢查 ReactiveCommand 的CanExecute更改狀態(tài)的次數(shù),以及它是真還是假,每次變量之一發(fā)生變化時(shí)。


[Fact]

public void TestMethod1()

{

    var objectList = new ReactiveList<IMyObject>(

        initialContents: new[] { new MyObject(), new MyObject() },

        resetChangeThreshold: 0.3,

        scheduler: ImmediateScheduler.Instance);


    objectList.ChangeTrackingEnabled = true;


    IMyViewModel myViewModel = new MyViewModel

    {

        ObjectList = objectList,

        MyObject = new MyObject()

    };


    var canExecute = myViewModel.Save

        .CanExecute

        .CreateCollection(scheduler: ImmediateScheduler.Instance);


    Assert.Equal(1, canExecute.Count);

    Assert.False(canExecute[0]);


    myViewModel.ObjectList[0].Active = true;

    Assert.Equal(2, canExecute.Count);

    Assert.True(canExecute[1]);


    myViewModel.MyObject.Active = true;

    Assert.Equal(2, canExecute.Count);


    myViewModel.IsBusy = true;

    Assert.Equal(3, canExecute.Count);

    Assert.False(canExecute[2]);


    myViewModel.IsBusy = false;

    Assert.Equal(4, canExecute.Count);

    Assert.True(canExecute[3]);


    myViewModel.MyObject.Active = false;

    Assert.Equal(4, canExecute.Count);


    var object1 = new MyObject { Active = true };

    var object2 = new MyObject { Active = true };

    myViewModel.ObjectList = new ReactiveList<IMyObject>(

        initialContents: new[] { object1, object2 },

        resetChangeThreshold: 0.3,

        scheduler: ImmediateScheduler.Instance);


    Assert.Equal(4, canExecute.Count);


    object1 = new MyObject { Active = false };

    object2 = new MyObject { Active = false };

    myViewModel.ObjectList = new ReactiveList<IMyObject>(

        initialContents: new[] { object1, object2 },

        resetChangeThreshold: 0.3,

        scheduler: ImmediateScheduler.Instance);


    Assert.Equal(5, canExecute.Count);

    Assert.False(canExecute[4]);

}


查看完整回答
反對(duì) 回復(fù) 2021-11-07
  • 2 回答
  • 0 關(guān)注
  • 483 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)