ionic:ngFor数组更改后不会自动更新

Mis*_*ith 2 ionic-framework ngfor ionic3 angular

离子新手在这里。我正在使用Ionic 3和BLE插件。该插件的工作方式是,您开始扫描Bluetooth设备,并收到每个新的扫描结果的通知,然后在完成后取消扫描。我只是想在ion-list每次接收到新的扫描结果时将元素附加到。

这个Cordova插件使用了回音,这些回音将离子包装到Observables和Promises中。该方法startScan返回Observable<any>,并且“ any”是一个对象,其中包含有关检测到的BLE设备的信息。

我首先尝试将此可观察对象直接插入ngFor中:

<ion-list>
    <button ion-item *ngFor="let result of results | async">
        {{ result | json}}
    </button>  
</ion-list>
Run Code Online (Sandbox Code Playgroud)

调用开始扫描返回了可观察到的结果:

this.results = this.ble.startScan([]);
this.results.subscribe(...);
Run Code Online (Sandbox Code Playgroud)

但是我听说这ngFor仅适用于数组,因此它需要一个Observable<Array>而不是单个对象的可观察对象。因此,我放弃了Observable并改为使用数组。异步管道不再起作用,所以我不得不修改列表:

<ion-list>
    <button ion-item *ngFor="let result of results">
        {{ result | json}}
    </button>  
</ion-list>
Run Code Online (Sandbox Code Playgroud)

然后将的类型更改resultsArray<any>。现在,扫描代码如下所示:

this.ble.startScan([])
.subscribe(device => {
    this.results.push(device); //Does not work    
});
Run Code Online (Sandbox Code Playgroud)

但是,直到屏幕上的某些其他组件发生更改,列表才会显示。显然,Angular不会检测到Array元素内部的更改,它仅检测到对象内引用和属性的更改。因此,我尝试了这种无效的技巧:

this.ble.startScan([])
.subscribe(device => {
    this.results = this.results.concat([device]); //Does not work    
});
Run Code Online (Sandbox Code Playgroud)

但是,即使那样也没有用。然后,经过几个小时的阅读,我知道了这个所谓的东西ChangeDetector应该可以解决问题。我尝试了OnPush检测策略,并且默认设置也无效:

this.ble.startScan([])
.subscribe(device => {
    this.results = this.results.concat([device]);
    this.changeDetector.markForCheck() //Does not work    
});
Run Code Online (Sandbox Code Playgroud)

当然,这是行不通的,因为它只是标记要检查,而此时并没有执行检查。

TL; DR ELI5在地球上,您需要在Ionic(或Angular)中做什么才能将元素添加到列表中?

Fre*_*ede 6

尝试detectChanges()代替markForCheck()

也许您想看看这个方法

作者使用ngZones run()将找到的设备添加到列表,其中包括changeDetection。非常有趣的恕我直言。这是一篇关于ngZone不错的文章