假設我有下面的類:觀察變化成功
public class Person : ReactiveObject, IEditableObject
{
private string name;
private string nameCopy;
public string Name
{
get { return this.name; }
set { this.RaiseAndSetIfChanged(ref this.name, value); }
}
public void BeginEdit()
{
this.nameCopy = this.name;
}
public void CancelEdit()
{
this.name = this.nameCopy;
}
public void EndEdit()
{
}
}
現在假設我想創建一個可觀察序列(的Unit
)認爲,「滴答」每當一個變化致力於到Name
。也就是說,我只關心Name
在BeginEdit
的呼叫和對EndEdit
的後續呼叫之間發生的更改。在調用CancelEdit
之前的任何更改都應該被忽略,並且順序不應該勾選。
我正在努力讓自己的腦袋圍繞如何與Rx做到這一點。看來我需要在某個地方的流水線狀態,以便知道這個變化是否發生在BeginEdit
/EndEdit
調用窗口期間。我想我可以給所有的東西打上時間戳,比較時間戳,但這似乎是一個令人討厭的黑客攻擊。
我就八九不離十使用編輯操作的專用Subject
與Observable.Merge
一起:
public class Person : ReactiveObject, IEditableObject
{
private readonly Subject<EditAction> editActions;
private readonly IObservable<Unit> changedDuringEdit;
private string name;
private string nameCopy;
public Person()
{
this.editActions = new Subject<EditAction>();
var nameChanged = this.ObservableForProperty(x => x.Name).Select(x => x.Value);
var editBeginning = this.editActions.Where(x => x == EditAction.Begin);
var editCommitted = this.editActions.Where(x => x == EditAction.End);
this.changedDuringEdit = nameChanged
.Buffer(editBeginning, _ => editCommitted)
.Where(x => x.Count > 0)
.Select(_ => Unit.Default);
}
public IObservable<Unit> ChangedDuringEdit
{
get { return this.changedDuringEdit; }
}
public string Name
{
get { return this.name; }
set { this.RaiseAndSetIfChanged(ref this.name, value); }
}
public void BeginEdit()
{
this.editActions.OnNext(EditAction.Begin);
this.nameCopy = this.name;
}
public void CancelEdit()
{
this.editActions.OnNext(EditAction.Cancel);
this.Name = this.nameCopy;
}
public void EndEdit()
{
this.editActions.OnNext(EditAction.End);
}
private enum EditAction
{
Begin,
Cancel,
End
}
}
然而,如果一些變化被取消,然後一個承諾,可觀察到的蜱上犯了幾次(一次每個事先取消,並再次提交)。更何況我得到了一個我並不需要的List<Unit>
這個事實。在某種程度上,這仍然能夠滿足我的使用案例,但不是我的好奇心或代碼感。
我覺得應該Join
解決這個相當優雅:
var nameChanged = this.ObservableForProperty(x => x.Name).Select(_ => Unit.Default);
var editBeginning = this.editActions.Where(x => x == EditAction.Begin);
var editCommitted = this.editActions.Where(x => x == EditAction.End);
var editCancelled = this.editActions.Where(x => x == EditAction.Cancel);
var editCancelledOrCommitted = editCancelled.Merge(editCommitted);
this.changedDuringEdit = editBeginning
.Join(nameChanged, _ => editCancelledOrCommitted, _ => editCancelledOrCommitted, (editAction, _) => editAction == EditAction.End)
.Where(x => x)
.Select(_ => Unit.Default);
但是,這也不行。看來Join
沒有訂閱editCancelledOrCommitted
,原因我不明白。
任何人有任何想法如何去幹淨這個?
尼斯布蘭登。這就像我認爲_you_想要的那樣:在「編輯」過程中發生的每個變化都會在您提交時發送給您。然而,看起來肯特只想要一個「單位」,不知道爲什麼。 –
@LeeCampbell是的,我也有點困惑。我會添加一個變化來做到這一點。 – Brandon
是的,我只是想讓一個單位發出變化信號 - 我不在乎具體發生了什麼變化,也沒有在編輯過程中更改了多少屬性。實際上,我的視圖模型代表配置,另一個視圖模型需要在配置發生任何更改時自刷新。我期待着嘗試一下。稍後我會這樣做。謝謝。 –