我有一个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模板使用)
-
而不是设置一个布尔值,我试着传递
collapsed
或visible
的文字字符串 -
使用
*ngIf
和Visibility
属性 -
使用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 回答
无需在N Angular-2应用程序中使用Observable - 而是使用角度绑定技术 . 我注意到的另一件事是你也使用了vanilla NativeScript的绑定语法,它与N Angular-2应用程序的绑定语法不兼容 .
区别在于: NativeScript Core 绑定语法:
NativeScript + Angular-2 绑定语法:
有关如何绑定回调数据的示例可以找到here基本上,您应该执行以下操作
最后用ng-2语法绑定它(示例显示单向绑定)
更多关于this documentation article中NativeScript Angular-2中的数据绑定
附:当使用TypeScript lambda时,你 do not need 来做var = this;在回调中保留 this 的范围含义 . 参考:https://basarat.gitbooks.io/typescript/content/docs/arrow-functions.html