首页 文章

nativescript-angular - 从服务运行回调时,UI不会更新

提问于
浏览
0

我有一个nativescript-angular应用程序运行蓝牙服务连接到外围设备(设备) . 该应用程序会显示一个标签,其中包含一条消息,表明尚未将蓝牙设备连接到运行应用程序的移动设备 . 我要做的是更新UI,以便标签在连接发生时消失(并在发生断开连接时重新出现) .

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

您可以看到代码是一团糟,但原因是我已经尝试使用我提到过的每一个可能的操作组合,这可能有助于我更新UI - 但是没有无济于事 .

以下是我之前尝试过的不起作用的事情:

zonedCallback()

  • 回调回调

  • 回调 ngZone.run()

  • 手动更新Component的变量值(由tns.html模板使用)

  • 而不是设置一个布尔值,我试着传递 collapsedvisible 的文字字符串

  • 使用 *ngIfVisibility 属性

  • 使用angular的 Renderer.listen

  • 使用nativescript的 Observable 类( import { Observable } from "data/observable" )和 .notify() 功能发出事件侦听NSAppComponent中的该事件 . BluetoothScanner 会扩展 Observable

  • 使用rxjs BehaviorSubject object( import { Observable } from "rxjs/BehaviorSubject"

  • 使用Angular的 changeDetectorRef 对象在更新变量后调用UI的更新

  • 设置一个Observable绑定到页面 . (注意它's possible that I haven' t正确设置将Observable绑定到页面对象[基于我在上面提到的代码中尝试做的事情]) .

通过所有这些,我能够更新变量值,但不更新UI . 实际更新我的UI的唯一事情是当我在源自UI事件(例如按钮点击事件处理程序)的调用中执行变量值更改时 .

1 回答

  • 4

    无需在N Angular-2应用程序中使用Observable - 而是使用角度绑定技术 . 我注意到的另一件事是你也使用了vanilla NativeScript的绑定语法,它与N Angular-2应用程序的绑定语法不兼容 .

    区别在于: NativeScript Core 绑定语法:

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

    NativeScript + Angular-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;
                }
            });
        });
    }
    

    最后用ng-2语法绑定它(示例显示单向绑定)

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

    更多关于this documentation article中NativeScript Angular-2中的数据绑定

    附:当使用TypeScript lambda时,你 do not need 来做var = this;在回调中保留 this 的范围含义 . 参考:https://basarat.gitbooks.io/typescript/content/docs/arrow-functions.html

相关问题