离子3和Ngzone()不起作用 [英] Ionic 3 and Ngzone() not working

查看:117
本文介绍了离子3和Ngzone()不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我想在蓝牙连接完成后执行某些操作,反之亦然。

处理连接和添加成功和失败处理程序的方案,并在这些处理函数中将标志更改为 True False

我使用console.log打印了该值,它在组件文件中更改但不反映在HTML中。

我尝试使用 ngZone ,但它无效。

成功和失败处理代码如下:



BluetoothService

 从@ angular / core导入{Injectable}; 
从'@ ionic-native / ble'导入{BLE};


@Injectable()
导出类BlueToothService {

构造函数(private ble:BLE){
}

public connect =(deviceId,onConnect,onFailure)=> {
this.ble.isConnected(deviceId)
.then(response => {
console.log(BlueToothService :: isConnected Function :: success :: device ---- ,响应);
onConnect(响应);
},
错误=> {
this.ble.connect(deviceId)
.subscribe(response => ; {
console.log(BlueToothService :: connect Function :: success :: device ----,response);
onConnect(response);
},
error => {
console.log(BlueToothService :: connect Function :: error :: device ----,error);
onFailure(error);
});
});
}}

组件文件



< pre class =lang-ts prettyprint-override> 从'@ angular / core'导入{Component,NgZone};
从'ionic-angular'导入{Events,IonicPage,NavController,NavParams,ViewController};

从'../../../providers/bluetooth/bluetooth.service'导入{BlueToothService};

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

public connectToBLE(){
this.blueToothService.connect(this.deviceId,onConnectionSuccess,onConnectionFailure); //假设设备ID已经存在
}

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

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

HTML

 < ion-content> 

< div text-center * ngIf =!isBluetoothConnected>
蓝牙连接失败
< / div>

< div text-center * ngIf =isBluetoothConnected>
蓝牙连接成功
< / div>

< button ion-button full class =primaryBlockButton(click)=connectToBLE()>点击< / button>

< / ion-content>


解决方案

由于console.log确实在您的案例数据中确认实际上是更改,而视图(模板)没有得到更新 - 这暗示没有发生更改检测。



验证您是否已经尝试过hack 并且根据你在评论中它起作用:

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

基本上,hack将您的数据更改包装为Angular选择的异步(setTimeout)活动。



现在要解决这个问题,您可以确保在您的情况下通过Angular自然拾取的事件发生数据更改(例如,添加自定义甚至监听器)。



或尝试在数据更改后手动更改检测来检测更改:



导入CDR:

 从'@ angular / core'导入{ChangeDetectorRef}; 

注入:

 构造函数(私有cdr:ChangeDetectorRef){} 

将其添加到您的方法中:

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

尝试这种方法,因为我认为它会比黑客更好。



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 => {
                console.log("BlueToothService :: isConnected Function :: success :: device----", response);
                onConnect(response);
            },
            error =>  {
                this.ble.connect(deviceId)
                    .subscribe(response => {
                        console.log("BlueToothService :: connect Function :: success :: device----", response);
                        onConnect(response);
                    },
                    error =>  {
                        console.log("BlueToothService :: connect Function :: error :: device----", 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;
            console.log("isBluetoothConnected---", this.isBluetoothConnected);      
        });
    };

    private onConnectionFailure = (reason) => {
        this.zone.run(() => {
            this.isBluetoothConnected = false;
            console.log("isBluetoothConnected---", this.isBluetoothConnected);      
        });
    } }

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>

解决方案

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.

这篇关于离子3和Ngzone()不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆