我正在使用Angular 2,并且发现了意外的行为。
我有一个数据源类,该类扩展了DataSource,具有两个变量:
private archives = new BehaviorSubject<MyArchive[]>([]);
public archives$: Observable<MyArchive[]> = this.archives.asObservable();
private filteredArchive: MyArchive[];
我在课堂上以这种方式更新档案:
this.archives.next(this.filteredArchive);
在另一个类的外部,我尝试订阅可观察的对象,但是它不起作用:
ngAfterViewInit(): void {
this.dataSource.archives$.subscribe((archive: Array<MyArchive>) => {
console.log(archive.length);
console.log(archive);
console.log(archive.length);
}
}
在控制台日志中它打印:
0
<THE ARCHIVE WITH AN OBJECT INSIDE AS IT SHOULD BE, WITH LENGTH = 1>
0
因为长度为0,所以我不能对归档变量进行迭代。
答案 0 :(得分:2)
在您订阅之前已经发出该值的问题。将可观察对象视为电视流,如果您在电视节目结束后打开电视(在推送数据后订阅),就不会看到电视节目,那么您的数据就像该电视节目上的电视节目一样。如果您希望观察者保留最后一个值,则可以使用“扫描”运算符,如下所示:
export const reducer = () =>
scan<MyArchive[]>((archive, update) => {
//update your Archive or simply overwrite the value
archive = update
return archive
}, []);
export class datasource {
archives$ : Observable<MyArchive[]>;
archives : Subject<MyArchive[]> = new Subject([]);
update(newMyArchive: MyArchive[]) {
this.archives.next(newMyArchive);
}
constructor(public http: HttpClient) {
this.archives$ = this.archives.pipe(
reducer(),
//use the shareReplay so all your subscribers get the same values
shareReplay(1)
);
this.archives$.subscribe();
}
,您可以使用数据源类中的update方法更新Arcjive,例如:
this.update(filteredArchive)
答案 1 :(得分:1)
我不确定为什么要重复创建archives$
和archives
。您只需一个BehaviorSubject就可以做到这一点。
我认为您应该这样做:
// Create a BehaviorSubject for MyArchive[]
public archives$: BehaviorSubject<MyArchive[]> = new BehaviorSubject<MyArchive[]>([]);
// Create a private filtered Array for MyArchive.
private filteredArchive: MyArchive[];
然后
this.archives$.next(this.filteredArchive);
答案 2 :(得分:1)
使用此语句时:
console.log(archive);
在控制台中显示对archive
对象的引用(请参见the MDN documentation)。当您在控制台中(通过单击箭头)检查对象时,其内容可能与执行console.log
语句时的内容不同。
为了查看特定时刻的实际内容,您应该输出对象的字符串表示形式:
console.log(archive.toString());
console.log(JSON.stringify(archive));
您可以练习this stackblitz来查看各种控制台输出。
答案 3 :(得分:0)
我解决了这个问题。 我忘记了this.filteredArchive是由HTTP GET请求更新的。我试图使用forEach在this.filteredArchive中推送数据,但是当接收到所有数据时,我忘记了调用then()。 因此,我试图使用订阅访问尚未准备好的结果。
感谢大家的答复!