我正在使用原生蓝牙串行库并尝试模拟数据以便在浏览器中进行测试。通过实验(以及一点阅读),似乎这样做的方法是检查'cordova'平台:
export class BluetoothServiceWrapper implements OnDestroy, OnChanges {
...
private isEmulated:boolean = true;
...
constructor(platform:Platform) {
platform.ready().then(() => {
this.isEmulated = !platform.is('cordova');
});
}
奇怪的是,这在某些方面有效:
connect(device:BluetoothDevice) {
return Observable.create(observer => {
...
if (!this.isEmulated) {
...
}else{
... // this is executed in the browser
}
}
}
但在其他部分中,this.isEmulated未定义:
write(data:any):Promise<any> {
if (!this.isEmulated) {
return BluetoothSerial.write(data);
} else {
.... // this never gets executed
}
}
我是否过于复杂,并且有一种更简单的方法来检查我们是否使用浏览器/模拟?或者上下文的传递方式是否有错误?
我应该提到两种方法在访问“this”即BluetoothServiceWrapper成员时获得相同的成员。在'write'函数的情况下,虽然isEmulated变量是隐藏/未定义的。
答案 0 :(得分:0)
好的,这是一个陷阱。原帖中缺少的重要信息是我有另一个组件/服务执行以下操作:
if (!this.isConnected && (!this.isConnecting)) {
this.bluetoothServiceWrapper.connect(device).subscribe(data => this.tuningModuleService.onData(data), console.error);
this.tuningModuleService.setOutputFunction(this.bluetoothServiceWrapper.write);
}
在上面的服务中,我将调用this.write('somedata'),使用上面给出的函数作为参考。
服务:
outputToSerialFn: any;
constructor(applicationRef: ApplicationRef, platform: Platform) {
...
// default (mock) output function
this.outputToSerialFn = function (data) {
return new Promise((resolve, reject) => {
console.log('Mock BT OUT', data);
})
};
}
setOutputFunction(outputToSerialFn: any) {
this.outputToSerialFn = outputToSerialFn;
}
问题在于,在调用期间, write 函数将使用它来获取服务的范围,而不是使用BluetoothWrapper服务。
一种解决方案是将上面的调用替换为:
this.tuningModuleService.setOutputFunction(this.bluetoothServiceWrapper.write.bind(this.bluetoothServiceWrapper));
关键词是 bind 。
这可能不是最好的模式,但可能会帮助那些也在努力解决这个问题的人。这里的教训是将函数作为参数传递会覆盖原始函数范围。