angular - BehaviorSubject:为什么不使用 next 就可以工作
问题描述
我有一个 Angular 应用程序,并为我的联系人列表创建了一个类,其中包括:
export interface Contact {
id: number;
name: string;
address: string;
}
export class ContactList {
private contactList: Contact[];
private contactNumber: number;
public getContactList(): Contact[] {
return this.contactList;
}
// Methods to add, modify and remove a contact
}
然后我有一个实例化这个类的服务,创建一个BehaviorSubject来与其他组件共享它,并有一些公共方法。
export class ContactListService {
public contactList: ContactList;
private contactList$: BehaviorSubject<Contact[]>;
constructor() {
this.contactList = new ContactList(FAKE_CONTACTS);
this.contactList$ = new BehaviorSubject<Contact[]>(this.contactList.getContactList());
}
public getContactList(): BehaviorSubject<Contact[]> {
return this.contactList$;
}
public deleteContact(contactId: number): void {
this.contactList.deleteContact(contactId);
}
public addContact(newName: string, newAddress: string): void {
this.contactList.addContact(newName, newAddress);
}
public modifyContact(contactId: number, newName?: string, newAddress?: string): void {
this.contactList.modifyContact(contactId, newName, newAddress);
}
}
然后,在一个组件中,我订阅了BehaviorSubject并将值影响到我的组件的一个属性。
ngOnInit() {
this.contactListSubscription = this.contactListService.getContactList().subscribe((newContactList) => {
this.contactList = newContactList;
});
}
所以它正在工作(即,当我通过服务执行操作时,一切都会更新)。但我不明白的是,订阅的内容(即。this.contactList = newContactList
)只在订阅时执行一次,而不是每次发生动作时执行。即使我通过 contactListService 方法更改内容。即使我取消订阅,比如订阅后 2 秒(例如使用 setTimeout),取消订阅后内容始终是最新的......
起初,我什至不明白为什么它在服务中工作而不执行contactList$.next(this.contactList.getContactList())
修改对象的每个操作。
所以看起来我传递了一些引用而不是类的内容?我想我不明白BehaviorSubject是如何工作的!
解决方案
JavaScript总是传递对对象的引用。
因此,contactList
组件中的数组是对存储在您的ContactList.contactList
属性中的相同、唯一数组的引用。
因此,您修改了数组,组件引用了这个修改后的数组,Angular 检测到数组中的更改,并将更改应用到 DOM。
ContactList
如果方法中的方法用另一个(修改后的副本)替换了数组,它就不再起作用了,例如
this.contactList = [this.contactList..., newContact]
在这种情况下,组件将继续引用先前未修改的数组。
用代码来说明:
service.contactList = ['John', 'Mary'];
component.contactList = service.contactList; // the exact, same array
service.contactList.push('Helen'); // add an element to the unique array
console.log(component.contactList); // logs John, Mary, Helen: it's the same, unique array
service.contactList = ['Jack']; // now the service references a second, different array
console.log(component.contactList); // Still logs John, Mary, Helen
推荐阅读
- sql - 使用 Node 和 DB2 将多个 OR 链接到 WHERE 子句
- excel - 如何检查excel单元格是否从选择下拉选项更改
- reactjs - 在更新组件之前进行 React 渲染
- javascript - 错误无法读取未定义的属性“Lon”
- asp.net-core - asp.net 核心不是依赖注入 .net 框架 4.5.1 库
- python - Docker 身份验证中的 Flask + Bokeh
- python - 如何使用 pandas 制作新的 df 列以使用正则表达式获取列名和值?
- html - HTML/SQL 表格格式化
- jquery - .每个都不会不断循环
- vb.net - 如何使用 vb.net 获取数字的百分比