我有一个角度服务,它有一个array of custom objects
和一个observable
of
这个数组。
可观察对象的外部组件subscribes
,但是当列表得到更改时不响应。
另外,对于observable
不会起反应的data source
设置为mat-table
。
服务(使用gRPC
流获取数据):
export class ScanService {
private scanCient: ScanClient = new ScanClient('http://' + window.location.hostname + ':8080', null, null);
private results: ItemModel[] = [];
readonly results$ = from(this.results);
constructor() { }
start(ip: string): boolean {
let stream = this.scanCient.listen(ip, {});
stream.on('data', (response) => {
this.results.push({
name: response.getName(),
type: response.getType(),
});
console.log('stream got item: ' + response.getName());
}
}
}
消费者:
export class ScanComponent implements OnInit {
//...
results$: Observable<ItemModel[]>;
constructor(private scanService: ScanService) { }
ngOnInit() {
this.results$ = this.scanService.results$;
this.results$.subscribe({next: function(results){console.log('subscriber got item: ', results);}});
}
onScan() {
this.scanService.start(this.ip);
}
}
<table mat-table [dataSource]="results$" class="mat-elevation-z8">
在console output
中,我看到每个项目的stream got item
,但没有subscriber got item
,并且mat-table
仍然为空。
编辑:
我有一个使用of
的类似示例,该示例似乎可以正常工作。
区别在于gRPC
调用直接返回一个对象,而不是流。
服务:
export class DiscoveryService {
private deviceList: DeviceModel[] = [];
private discoveryCient: DiscoveryClient = new DiscoveryClient('http://' + window.location.hostname + ':8080', null, null);
constructor() {
}
getDeviceList(): void {
this.discoveryCient.devices(new EmptyProto(), {}, (err, reply) => {
const pbDeviceList = reply.getDevicesList();
for (const pbDevice of pbDeviceList) {
this.deviceList.push({ ip: pbDevice.getIp()});
}
});
}
observeDeviceList(): Observable<DeviceModel[]> {
return of(this.deviceList);
}
}
消费者:
export class DeviceListComponent implements OnInit {
deviceList$: Observable<DeviceModel[]>;
constructor(private discoveryService: DiscoveryService) { }
ngOnInit() {
// First get the observable to the list(which is still empty)
this.deviceList$ = this.discoveryService.observeDeviceList();
// Then tell the service to populate the list
this.discoveryService.getDeviceList();
}
}
<mat-nav-list *ngFor="let device of deviceList$ | async">
答案 0 :(得分:0)
积累评论中其他有用声音已经告诉您的内容:
您在这里面临两个问题。
of()vs from()
我在这里指的是another question。基本上,of([[1,2,3])创建一个可观察对象,它将像在数组上一样发出“ [1,2,3]”,因此您将得到一个发出,而from([1,2,3])将发出最后是“ 1”,然后是“ 2”和“ 3”。从您的result$
的使用情况来看,我猜您想使用of()
。
主题vs可观察
您希望将result
-Array的更新发布给result$
-Observable的订户,但是Observable一旦发出所有值,便完成了,因此它将自动完成发出订阅时存在的静态数据后,请取消订阅。
一个简单的解决方法是使用Subjects尤其是BehaviourSubjects而不是Observables。它们具有类似于发布商的特性。
const result$ = new BehaviourSubject<ItemModel[]>(this.result);
这些向所有新订阅者发出最后发出的值,并且还允许您通过调用其next()
方法向其订阅者释放新数据。
因此,您需要致电
result$.next(newValue);
代替
result = newValue;