web-dev-qa-db-ja.com

Ionic 3およびNgzoneが機能していません-結果をHTMLビューに更新していません


Bluetooth接続が完了した後に何らかのアクションを実行したい、またはその逆。
接続のシナリオを処理し、成功および失敗ハンドラーも追加し、これらのハンドラー関数でフラグをTrueおよびFalseに変更しました。
console.logを使用してその値を出力しました。コンポーネントファイルで変更されますが、HTMLには反映されません。
ngZoneを使用してみましたが、機能しません。
成功と失敗のハンドルコードは次のとおりです。

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);         
                    });            
        });
    } }

コンポーネントファイル

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>
6

Console.logは、ビュー(テンプレート)が更新されていないときにデータが実際に変更されたことを確認するため、変更検出が行われていないことを示しています。

あなたがすでに「ハック」を試みたことを検証するために、そしてコメントのあなたによると、それはうまくいきました:

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

基本的に、ハックはデータの変更をAngularが取得する非同期(setTimeout)アクティビティに「ラップ」します」。

これに対処するために、Angularが自然に取得するイベントを介してケースのデータ変更が発生することを確認できます(たとえば、カスタムのリスナーを追加します)。

または、変更検出を使用して、データが変更された後に手動で変更を検出してみてください。

cDRのインポート:

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

それを注入します:

constructor (private cdr: ChangeDetectorRef) {}

メソッドに追加します。

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

ハックよりも優れていると思うので、このアプローチを試してください。

3
Sergey Rudenko