【发布时间】:2018-08-09 16:27:10
【问题描述】:
离子新手在这里。我正在使用 Ionic 3 和 BLE 插件。这个插件的工作方式是你开始扫描蓝牙设备,每个新的扫描结果都会通知你,然后当你完成后取消扫描。我只是想在每次收到新的扫描结果时将一个元素附加到 ion-list 中。
这个 Cordova 插件使用 ionic 封装到 Observables 和 Promises 中的回调。方法startScan 返回一个Observable<any>,“any”是一个包含检测到的BLE 设备信息的对象。
我首先尝试将这个 observable 直接插入到 ngFor:
<ion-list>
<button ion-item *ngFor="let result of results | async">
{{ result | json}}
</button>
</ion-list>
开始扫描的调用返回了 observable:
this.results = this.ble.startScan([]);
this.results.subscribe(...);
但是我听说ngFor 仅适用于数组,因此它需要Observable<Array> 而不是单个对象的可观察对象。所以我放弃了 Observable 并使用了一个数组。异步管道不再工作,所以我不得不修改列表:
<ion-list>
<button ion-item *ngFor="let result of results">
{{ result | json}}
</button>
</ion-list>
然后将results的类型改为Array<any>。扫描代码现在看起来像这样:
this.ble.startScan([])
.subscribe(device => {
this.results.push(device); //Does not work
});
但是直到屏幕中的一些其他组件发生变化,列表才会显示。显然 Angular 不会检测 Array 元素内部的变化,它只检测对象内部引用和属性的变化。所以我尝试了这个无能的黑客:
this.ble.startScan([])
.subscribe(device => {
this.results = this.results.concat([device]); //Does not work
});
但即使这样也没有用。然后经过几个小时的阅读,我知道了这个叫做ChangeDetector的东西,据称它应该可以解决问题。我尝试了 OnPush 检测策略,默认也没有用:
this.ble.startScan([])
.subscribe(device => {
this.results = this.results.concat([device]);
this.changeDetector.markForCheck() //Does not work
});
当然它不起作用,因为它只是标记检查,但在那一刻不执行检查。
TL;DR ELI5 你到底需要在 Ionic(或 Angular)中做什么才能将元素添加到列表中?
【问题讨论】:
-
如果没有其他方法,您可以尝试:
this.changeDetectorRef.detectChanges();。您可以在this post 中找到其他触发变更检测的方法。
标签: angular ionic-framework ionic3 ngfor