BehaviorSubject:为什么不使用 next 就可以工作
BehaviorSubject: why is it working without using next
我有一个 Angular 应用程序,我为我的联系人列表创建了一个 class,其中包括:
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
}
然后我有一个实例化此 class 的服务,创建一个 BehaviorSubject 以与其他组件共享它并具有一些 public 方法。
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())
。
所以好像我传递了一些引用而不是 class 的内容?我想我不明白 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
我有一个 Angular 应用程序,我为我的联系人列表创建了一个 class,其中包括:
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
}
然后我有一个实例化此 class 的服务,创建一个 BehaviorSubject 以与其他组件共享它并具有一些 public 方法。
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())
。
所以好像我传递了一些引用而不是 class 的内容?我想我不明白 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