通过 AngularJS 访问 Chrome 的 WebUSB

Accessing WebUSB of Chrome through AngularJS

我在通过 angularJS 为 chrome 使用 WebUSB API 时遇到问题。这是一个项目,我需要访问 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)
            }
        });
    };

尝试使用 angular 脚本时出现 DOMException 错误:

Must be handling a user gesture to show a permission request.

这是 web usb 的 requestDevice 函数所需要的,它应该是用户按钮单击或鼠标悬停。

这在第一个示例中工作正常,因为用户单击按钮触发该功能。

在第二个例子中,发生了同样的事情。我什至避免使用 ng-click 让本机事件侦听器尝试是否可行。但也没有运气。

谁能帮帮我? angularJS 出了什么问题?

我不确定第一个示例,但在第二个示例中,在调用 requestDevice() 之前,您等待 getDevices() 返回的承诺。这意味着您的异步函数的其余部分将在该承诺得到解决并且您的代码不再具有用户手势后被调用。

与其在每次点击时调用 getDevices(),我建议只在页面加载时调用一次,并使用事件侦听器(添加 navigator.usb.addEventListener('connect', ...))来检测页面加载后连接的设备。