[英]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.