首页 > 解决方案 > 为什么在angularjs中通过条形码扫描仪设备扫描条形码后我的函数多次调用?

问题描述

我正在开发销售点应用程序,当我通过条码扫描仪设备扫描条码时遇到问题,我的功能被多次调用。例如,当我第一次扫描条形码时,我的函数调用了一次,当我在不刷新页面的情况下扫描条形码时,函数调用了两次,当我第三次扫描条形码时,函数调用了 4 次,这意味着函数调用了 2 的倍数. 这是我的代码,请检查并纠正我的问题。

// 这是我的条码扫描器函数,在这个函数中有两个api,1用于通过长度大于或等于15的条码获取整个发票,2用于扫描条码后获取产品。

$scope.returnProductByScanner = function (cod) { 
    if($location.path() == "/returnSale"){
        if(cod != undefined){
            var n = cod.length;
            if(n == 15 || n > 15){
                var action = {"barcode": cod};
                var getDt = customerService.viewInvoiceOnBarcode(action);
                getDt.then(function(data){
                    if(data.status == "success"){
                        var so = data.SO;
                        so.return = "return";
                        var sop = data.SOProducts;
                        $scope.addParkedProductIntoBag(sop,so);
                    }else{
                        var msg = data.error;
                        $scope.responseMsg(msg,"Failed");
                    }
                })
            }else{
            // if($scope.newBagListOfProduct.length > 0){
                var action = {"barcode":cod,"userid":uid,"org_id":org_id};
                var getDt = customerService.getBarcodeScannedData(action);
                    getDt.then(function(data){
                        if(data.status == "success"){
                            var prodData = data.product;
                            $scope.addProductInBagSaleReturn(prodData);
                        }else{
                            var msg = data.msg;
                            $scope.responseMsg(msg,"Failed");
                        }
                    })
                // }else{
                //     var msg = "Please first add invoice for return!";
                //     $scope.responseMsg(msg,"Failed");
                // } 
            }
        }
    //$('input[name="myInput"]').focus();
    }else{
        cod = undefined;
    }
    $('input[name="myInput"]').focus();
};

// 这是我的 HTML 代码

 <div>     
    <div data-barcode-scanner="returnProductByScanner"></div>
    <div><input  name="myInput" type="text" 
                 data-ng-model="testvalueret"
                 id="t"  autofocus/>
    </div>
 </div>

// 这是我使用的贬义词。

 .directive('barcodeScanner', function() {
  return {
    restrict: 'A',    
    scope: {
        callback: '=barcodeScanner',        
      },      
    link:    function postLink(scope, iElement, iAttrs){       
        // Settings
        var zeroCode = 48;
        var nineCode = 57;
        var enterCode = 13;    
        var minLength = 3;
        var delay = 300; // ms

        // Variables
        var pressed = false; 
        var chars = []; 
        var enterPressedLast = false;

        // Timing
        var startTime = undefined;
        var endTime = undefined;

        jQuery(document).keypress(function(e) {            
            if (chars.length === 0) {
                startTime = new Date().getTime();
            } else {
                endTime = new Date().getTime();
            }

            // Register characters and enter key
            if (e.which >= zeroCode && e.which <= nineCode) {
                chars.push(String.fromCharCode(e.which));
            }

            enterPressedLast = (e.which === enterCode);

            if (pressed == false) {
                setTimeout(function(){
                    if (chars.length >= minLength && enterPressedLast) {
                        var barcode = chars.join('');                                                
                        //console.log('barcode : ' + barcode + ', scan time (ms): ' + (endTime - startTime));

                        if (angular.isFunction(scope.callback)) {
                            scope.$apply(function() {
                                scope.callback(barcode);  
                                alert(barcode);  
                            });
                        }
                    }
                    chars = [];
                    pressed = false;
                },delay);
            }
            pressed = true;
        });
    }
  };
})

标签: angularjsangularjs-directiveangular-promise

解决方案


将事件处理程序添加到外部元素的指令需要在作用域被销毁时删除这些事件处理程序:

app.directive('barcodeScanner', function() {
  return {
    restrict: 'A',    
    scope: {
        callback: '=barcodeScanner',        
      },      
    link:  function postLink(scope, iElement, iAttrs){       

       jQuery(document).on("keypress", keypressHandler);
       scope.$on("$destroy", function () {
           jQuery(document).off("keypress", keypressHandler);       
       });


       function keypressHandler(e) {            
            if (chars.length === 0) {
                startTime = new Date().getTime();
            } else {
                endTime = new Date().getTime();
            }
            //...
       }
    }
  }
})

AngularJS 框架在其操作过程中构建和销毁元素。当这些元素被销毁时,它们各自的范围也被销毁,并且应该执行任何必要的清理。


推荐阅读