2016-10-20 14 views
0

У меня есть одностороннее приложение, которое запускает службу bluetooth для подключения к периферийному устройству (устройству). Приложение представляет ярлык с сообщением о том, что Bluetooth-устройство еще не подключено к мобильному устройству, на котором запущено приложение. Что я пытаюсь сделать, так это обновить интерфейс, чтобы метка исчезла при возникновении соединения (и снова появится при отключении).nativescript-angular - пользовательский интерфейс не будет обновляться при выполнении обратного вызова из службы.

app.component.tns.html

<StackLayout orientation="vertical" marginBottom="50"> 
    <Label text="No bluetooth device detected." id="noBluetoothWarning" horizontalAlignment="center" color="#B11" *ngIf="bluetoothDisconnected" marginTop="30" visibility="{{ isBluetoothConnected ? 'collapsed' : 'visible' }}"></Label> 
</StackLayout> 

app.component.ts

export class NSAppComponent extends AppComponent implements OnInit { 


    pageData: Observable; 

    ngOnInit() { 
    this.bluetoothDisconnected = true; 

    let _page = <Page>topmost().currentPage; 
    _page.actionBarHidden = true; 
    _page.frame.bindingContext = this.pageData; 

    let that = this; 

    this.bluetoothScanner.connectionStateChangeEvent.subscribe((connectionState) => { 
     that.log.debug(`Am I in an angular zone? ${NgZone.isInAngularZone()}`); 
     this.ngZone.run(() => { 

     that.log.debug(`connectionStateEvent triggered! state is: ${connectionState}`); 

     that.bluetoothDisconnected = !connectionState; 

     that.pageData.set("isBluetoothConnected", connectionState); 

     that.pageData.notify({ object: that.pageData, eventName: Observable.propertyChangeEvent, propertyName: "isBluetoothConnected", value: connectionState }); 

     this.pageData.notify({ object: that.pageData, eventName: Observable.propertyChangeEvent, propertyName: "bluetoothDisconnected", value: !connectionState }); 
     }) 
    }); 
    } 

constructor(@Inject(LogService) public log: LogService, private ngZone: NgZone) { 
     this.pageData = new Observable(); 
     this.pageData.set("isBluetoothConnected", false); 
     this.bluetoothScanner = new BluetoothScanner(...); 
    } 
} 

bluetoothScanner.ts

export class BluetoothScanner { 
    private connectionState = new BehaviorSubject<boolean>(false); 
    ... 
    that.connectionState.next(true); 
} 

Вы можете видеть, что код беспорядок, но причина в том, что в течение месяца я пытался использовать каждую возможную комбинацию действий, о которых я упоминал, что может помочь мне обновить интерфейс, но нет.

Вот следующие вещи, которые я ранее пытавшаяся, которые не работали, а:

  • обертка обратный вызов в zonedCallback()
  • обертки обратный вызов в ngZone.run()
  • вручную обновить значение переменной компоненты (который используется по шаблону tns.html)
    • вместо установки логического значения, я попытаюсь передать литеральную строку collapsed или visible
  • использование *ngIf и Visibility свойства Observable класса
  • использование углового в Renderer.listen
  • использовать nativescript (в import { Observable } from "data/observable") с .notify() функциональности, чтобы излучать событие + слушать это событие в NSAppComponent. BluetoothScanner продлит Observable
  • использование rxjs BehaviorSubject объекта (import { Observable } from "rxjs/BehaviorSubject")
  • использования углового в changeDetectorRef объект для вызова для обновления пользовательского интерфейса после обновления переменных
  • установить наблюдаемый быть привязанными к странице. (примечание возможно, что я неправильно установил привязку Observable к объекту страницы [на основе того, что я пытался сделать в упомянутом выше коде]).

Через все это я смог обновить значение переменной, но не обновлять пользовательский интерфейс. Единственное, что действительно обновило мой интерфейс, это когда я предварительно сгенерировал изменение значения переменной в вызове, возникшем из события пользовательского интерфейса (например, обработчик события нажатия кнопки).

+0

Небольшая заметка. Я попытался использовать разные комбинации доступа к этому объекту в закрытии, а не использовать переменную 'this', как в моем примере, в этом случае ничего не изменилось. – NLev

ответ

3

Не нужно использовать Наблюдаемое в приложении N + Угловое-2 - вместо этого используйте методы углового связывания.Еще одна вещь, которую я заметил, это то, что вы также используете синтаксис привязки для ванильного NativeScript, который несовместим с синтаксисом привязки для приложения N + Angular-2.

Вот разница: NativeScript Ядро связывание Синтаксис:

visibility="{{ isBluetoothConnected ? 'collapsed' : 'visible' }}" 

NativeScript + Радиально-2 связывание Синтаксис:

[visibility]="isItemVisible ? 'visible' : 'collapsed'" 

Пример того, как связать данные из обратный вызов можно найти here в основном, вы должны сделать следующее

export class UsingConnectivityExampleComponent implements OnInit { 

public connectionType: string; // use this variable to for binding in your html 

constructor(private zone: NgZone) { 
} 

ngOnInit() { 
    connectivity.startMonitoring((newConnectionType: number) => { 
     this.zone.run(() => { 
      switch (newConnectionType) { 
       case connectivity.connectionType.none: 
        this.connectionType = "None"; // assign value 
        console.log("Connection type changed to none."); 
        break; 
       case connectivity.connectionType.wifi: 
        this.connectionType = "Wi-Fi"; // assign value 
        console.log("Connection type changed to WiFi."); 
        break; 
       case connectivity.connectionType.mobile: 
        this.connectionType = "Mobile"; // assign value 
        console.log("Connection type changed to mobile."); 
        break; 
      } 
     }); 
    }); 
} 

И, наконец, связать его с синтаксисом нг-2 (пример показывает один из способов связывания)

<Label [text]="connectionType"></Label> 

больше о связывании данных в NativeScript + радиально-2 в this documentation article

P.S. При использовании лямбда TypeScript вам не нужен, чтобы сделать var that = this;, чтобы сохранить значение области в обратных вызовах. Ссылка: https://basarat.gitbooks.io/typescript/content/docs/arrow-functions.html

+0

Спасибо за ответ Ник. 'обновлено – NLev

+0

(mobile shenanigans) Спасибо за ответ Nick. Я обновил привязку в HTML в квадратных скобках и обновил код, чтобы использовать «NgZone.run()», а также «zonedCallback» (отдельно). К сожалению, в этом случае пользовательский интерфейс по-прежнему не обновляется. – NLev

+0

@NLev Вы тоже удалили связанный с Observable код? Вероятно, вам даже не нужно использовать NgZone. – rrjohnson85