[英]BehaviorSubject partial change does not trigger subscription
我正在使用Typescript 3.4.5和Angular 8。
考慮以下接口:
// This is an interface which represents a piece of data, which will be partially updated
export interface TextBrick {
kind: 'text';
content: string;
}
export class TestService {
test$ = new BehaviorSubject<TextBrick>({kind: 'text', content: 'initial'});
get test(): TextBrick {
return this.test$.value;
}
set test(v: TextBrick) {
console.log('set', v);
this.test$.next(v);
}
}
這個想法是訂閱test$
BehaviorSubject來觀察test.content
變化。
現在考慮以下測試:
test('test', () => {
const instance = new TestService();
// Watch subscription
instance.test$.subscribe((v) => console.log('sub', v));
// 1) Full replace, subscription triggered
instance.test = {kind: 'text', content: 'fullreplace'};
// 2) Partial replace, subscription not triggered
instance.test.content = 'aa';
// But the value of the BehaviorSubject was updated! WTF?!
console.log('end', instance.test);
});
控制台輸出如下:
sub { kind: 'text', content: 'intitial' } // Expected behavior
set { kind: 'text', content: 'fullreplace' } // Expected behavior
sub { kind: 'text', content: 'fullreplace' } // Expected behavior
end { kind: 'text', content: 'aa' } // Sounds really weird!
設置instance.test.content
時,“部分設置器”顯然存在問題(我不知道如何命名)。 我仔細閱讀了setter上的Typescript文檔 ,但未提及該用例。
我的第一個假設是未調用set test()
,這是有道理的,因為當我在setter中添加console.log時,我看不到'aa'
的“部分”設置。 但是,如何在不觸發我的訂閱回調的情況下更新行為主體的值?
任何幫助或資源將不勝感激!
instance.test = {kind: 'text', content: 'fullreplace'};
這行調用setter函數
instance.test.content = 'aa';
此行調用getter函數,然后對行為主體的內容進行突變,而您不應對行為主體的內容進行突變。
獲取值,然后使用新對象更新值,我們不會在反應式編程領域中更改對象。
const value = instance.test;
instance.test = { ...value, content: 'aa' };
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.