Доступ к WebUSB Chrome через AngularJS
У меня возникла проблема при использовании API-интерфейсов WebUSB для chrome через angularJS. Это проект, в котором мне нужно получить доступ к термопринтеру esc/pos для печати счета.
В обычном JavaScript:
HTML:
<button id="connect">Connect</button>
Javascript:
document.addEventListener('DOMContentLoaded', async () => {
try{
let devices = await navigator.usb.getDevices({
filters: [{
vendorId: VENDOR_ID,
productId: PRODUCT_ID
}]
});
let button = document.getElementById('connect');
button.addEventListener('click', async () => {
if (devices.length === 0) {
var device;
let devices = [];
try {
device = await navigator.usb.requestDevice({
filters: [{
vendorId: VENDOR_ID,
productId: PRODUCT_ID
}]
});
}
catch (error) {
console.log(error)
}
}
else {
device = devices[0];
}
console.log('open');
await device.open();
console.log('opened:', device);
await device.selectConfiguration(1); // Select configuration #1 for the device.
await device.claimInterface(0); // Request exclusive control over interface #0.
console.log(await device.transferOut(2,buffer));
})
}
catch (error) {
console.log(error)
}
в angularjs: HTML:
<button class="btn btn-warning" ng-init="newinvscopetest.bindPrint()" id="print">Print</button>
контроллер:
newinvscopetest.bindPrint = function (){
let button = document.getElementById('print');
button.addEventListener('click', async () => {
let device;
let devices = [];
const VENDOR_ID = 0x0FE6;
const PRODUCT_ID = 0x811E;
try {
devices = await navigator.usb.getDevices({
filters: [{
vendorId: VENDOR_ID,
productId: PRODUCT_ID
}]
});
if (devices.length === 0) {
try {
device = await navigator.usb.requestDevice({
filters: [{
vendorId: VENDOR_ID,
productId: PRODUCT_ID
}]
});
}
catch (error) {
console.log(error)
}
}
else {
device = devices[0];
}
console.log('open');
await device.open();
console.log('opened:', device);
await device.selectConfiguration(1); // Select configuration #1 for the device.
await device.claimInterface(0); // Request exclusive control over interface #0.
let buffer = newinvscopetest.getPrintData();
console.log(await device.transferOut(2,buffer));
}
catch (error) {
console.log(error)
}
});
};
При попытке использовать угловой скрипт DOMException выдает ошибку:
Должен обрабатывать пользовательский жест, чтобы показать запрос на разрешение.
Это требуется функцией requestDevice веб-usb, которая должна быть нажатием пользовательской кнопки или наведением мыши.
И это хорошо работает в первом примере, потому что пользователь нажимает кнопку, чтобы вызвать функцию.
Во втором примере происходит то же самое. Я даже избегал ng-click, чтобы иметь встроенный прослушиватель событий, чтобы попробовать, если это работает. Но с этим тоже не повезло.
Может кто-нибудь мне помочь? Что не так в angularJS?
1 ответ
Я не уверен насчет первого примера, но во втором примере перед вызовом requestDevice()
вы ждете обещание, возвращенное getDevices()
, Это означает, что остальная часть вашей асинхронной функции вызывается после того, как это обещание разрешено, и ваш код больше не имеет пользовательского жеста.
Вместо звонка getDevices()
при каждом нажатии я рекомендую вызывать его только один раз при загрузке страницы и использовать прослушиватель событий (добавляется с navigator.usb.addEventListener('connect', ...)
) для обнаружения устройства, подключенного после загрузки страницы.