Ionic 3 and Ngzone is not working - not updating the results to HTML view

笑着哭i 提交于 2020-01-02 03:36:06

问题



I want to perform some action after Bluetooth connection is done and vice versa.
Handled scenarios for connection and added success and failure handler also, and changing a flag to True and False in those handler functions.
I printed that value using console.log, it changes in a component file but does not reflect in HTML.
I tried using ngZone, but it's not working.
Success and failure handle code are as follows:

BluetoothService

import { Injectable } from "@angular/core";
import { BLE } from '@ionic-native/ble';


@Injectable()
export class BlueToothService {

    constructor(private ble: BLE){
    }

     public connect = (deviceId, onConnect, onFailure) => {
        this.ble.isConnected(deviceId)
            .then(response => {                   
                onConnect(response);
            },
            error =>  {
                this.ble.connect(deviceId)
                    .subscribe(response => {
                        onConnect(response);
                    },
                    error =>  {
                        onFailure(error);         
                    });            
        });
    } }

Component File

import {Component, NgZone} from '@angular/core';
import {Events, IonicPage, NavController, NavParams, ViewController} from 'ionic-angular';

import {BlueToothService} from '../../../providers/bluetooth/bluetooth.service';

@IonicPage()
@Component({
    selector: 'test-data',
    templateUrl: 'test-data.html',
})
export class AddTestKitDataPage {
    public isBluetoothConnected: boolean = false;
    public deviceId: any;

    public connectToBLE() {
        this.blueToothService.connect(this.deviceId, onConnectionSuccess, onConnectionFailure);  //Assume device id is already present
    }

    private onConnectionSuccess = (reason) => {
        this.zone.run(() => {
            this.isBluetoothConnected = true;       
        });
    };

    private onConnectionFailure = (reason) => {
        this.zone.run(() => {
            this.isBluetoothConnected = false;
        });
    } }

HTML

<ion-content>

    <div text-center *ngIf="!isBluetoothConnected">
        Bluetooth Connection failure
    </div>

    <div text-center *ngIf="isBluetoothConnected">
        Bluetooth Connection success
    </div>

    <button ion-button full class="primaryBlockButton" (click)="connectToBLE()">Click</button>

</ion-content>

回答1:


Since console.log does confirm that in your case data actually changes, while the view (template) is not getting an update - this hints that Change Detection is not taking place.

To validate that you did already try the "hack" and according to you in comments it worked:

private onConnectionSuccess = (reason) => { 
    this.zone.run(() => { 
        setTimeout(() => { 
            this.isBluetoothConnected = true; 
            console.log("isBluetoothConnected---", this.isBluetoothConnected); 
        },0) 
     }); 
};

Basically the hack "wraps" your data change into an async (setTimeout) activity that Angular picks up.

Now to address it you could either ensure that data change in your case happens via event that Angular picks up naturally (add custom even listener for example).

Or try to use change detection to detectChanges manually after data changed:

import CDR:

import { ChangeDetectorRef } from '@angular/core';

inject it:

constructor (private cdr: ChangeDetectorRef) {}

Add it to your method:

private onConnectionSuccess = (reason) => { 
    this.isBluetoothConnected = true; 
    console.log("isBluetoothConnected---", this.isBluetoothConnected);
    this.cdr.detectChanges();
};

Try this approach as I think it will be better than the hack.



来源:https://stackoverflow.com/questions/50348907/ionic-3-and-ngzone-is-not-working-not-updating-the-results-to-html-view

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!