简体   繁体   中英

Call function in one JavaScript file from another, in a setTimeout, and using AngularJS

I have some code to detect a barcode scan. It was working when it was directly in an AngularJS controller. Since another controller needed to use that code also, I put the scan code in a separate JS file so they could both use it. My research showed that calling a JS file from another should work if I include them in the HTML page. I've done that. But after the scan code detects a scan, it tries to call a method on the other controller, but I get this error:

0x800a1391 - JavaScript runtime error: 'onBarcodeScan' is undefined

In barcodeScan.js:

setTimeout(function () {
    if (chars.length == 12) {
        var barcode = chars.join("");
        onBarcodeScan(barcode);  // Error occurs here
    }
    chars = [];
    pressed = false;
}, 500);

In my AngularJS controller:

var onBarcodeScan = function (barcode) {
    $scope.$apply(function () {
        $scope.state.userEnteredSubId = barcode;
        $scope.onSubmitSubId();
    });
}

What am I missing?

Note: My controller code is listed first in the index HTML page:

<script src="js/cassetteController.js"></script>
<script src="js/barcodeScan.js"></script>

I found a post that explained using events in an AngularJS factory . Here is the working code:

Controller:

scannerService.notify();

scannerService.subscribe($scope, function () {
    // Handle notification
    $scope.$apply(function () {
        $scope.state.userEnteredSubId = $rootScope.scan;
        $scope.onSubmitSubId();
    });
});

Factory:

app.factory('scannerService', ['$http', '$rootScope', function ($http, $rootScope) {
    var listenerAdded;

    return {
        subscribe: function (scope, callback) {
            var handler = $rootScope.$on('notifying-service-event', callback);
            scope.$on('$destroy', handler);
        },

        initialize: function () {
            if (listenerAdded) {
                return;
            }
            // From http://www.deadosaurus.com/detect-a-usb-barcode-scanner-with-javascript/:
            listenerAdded = true;
            var pressed = false;
            var chars = [];
            document.addEventListener('keydown', function (event) {
                // Ignore this if the user is hitting enter, or any other non-number.
                if (event.keyCode < 48 || event.keyCode > 57) {
                    return;
                }
                // Only capture numbers, because a subId is all numbers.
                if (event.keyCode >= 48 && event.keyCode <= 57) {
                    // Note: Theys keycodes are only for numbers along the top of the keyboard; the number pad uses a different range.
                    chars.push(String.fromCharCode(event.keyCode));
                }
                console.log(event.keyCode + ":" + chars.join("|"));
                if (pressed == false) {
                    // The JS setTimeout method would cause us to have to use $scope.apply(). Instead, just use Angular's $timeout.
                    // http://jimhoskins.com/2012/12/17/angularjs-and-apply.html
                    setTimeout(function () {
                        if (chars.length == 12) {
                            var barcode = chars.join("");
                            $rootScope.scan = barcode;
                            $rootScope.$emit('notifying-service-event');
                        }
                        chars = [];
                        pressed = false;
                    }, 500);
                }
                pressed = true;
            });
        }
    };
}]);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM