这里是 ionic 新手。我正在使用 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>
调用开始扫描返回可观察值:
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 不会检测数组元素内部的变化,它只检测对象内部引用和属性的变化。所以我尝试了这个低效的黑客:
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)中到底需要做什么才能将元素添加到列表中?
最佳答案
尝试 detectChanges()
而不是 markForCheck()
。
也许您想看看 this aproach .
作者使用 ngZones run()
将找到的设备添加到列表中,其中包括changeDetection。恕我直言,非常有趣。这是nice article about ngZone
关于angular - ionic : ngFor not updating automatically after changes in array,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49052475/