简体   繁体   中英

How to register a cordova event inside the angular controller within an hybrid application

I'm using Visual Studio>TypeScript>Cordova application to build foundation of my application. then i install angularJs 1.3 at it was required by mobile-angular-ui, and then install it.

The application has index.ts, which later it's compailation result will be placed inside appBundle.js ....

The file is like this and work just fine:

// For an introduction to the Blank template, see the following documentation:
// http://go.microsoft.com/fwlink/?LinkID=397705
// To debug code on page load in Ripple or on Android devices/emulators: launch your app, set breakpoints, 
// and then run "window.location.reload()" in the JavaScript Console.
var RavisMobileCordova;
(function (RavisMobileCordova) {
    "use strict";
    var Application;
    (function (Application) {
        function initialize() {
            document.addEventListener('deviceready', onDeviceReady, false);
        }
        Application.initialize = initialize;
        function onDeviceReady() {
            // Handle the Cordova pause and resume events
            document.addEventListener('pause', onPause, false);
            document.addEventListener('resume', onResume, false);
            // TODO: Cordova has been loaded. Perform any initialization that requires Cordova here.
        }
        function onPause() {
            // TODO: This application has been suspended. Save application state here.
        }
        function onResume() {
            // TODO: This application has been reactivated. Restore application state here.
        }
    })(Application = RavisMobileCordova.Application || (RavisMobileCordova.Application = {}));
    window.onload = function () {
        Application.initialize();
    };
})(RavisMobileCordova || (RavisMobileCordova = {}));
//# sourceMappingURL=appBundle.js.map

but when it's come to the stage, that i may be in need of calling an events inside my controller, i can't do that, the debugger detach and doesn't show any help full error.

i tried it with use of onResume for test propose, first by seeing this: https://groups.google.com/forum/#!topic/angular/nx3Csp8nu0A

and replacing the line :

document.addEventListener('resume', onResume, false);

with the following, and defining $scope.onResume=function... in my controller:

document.addEventListener('resume', $scope.onResume, false);

Failed!!!

Then i done document.addEventListener(...) within my own controller

Failed!!!

then i look closer at appBundle.js and saw if register on resume just when device ready is called, so i did this within the body of controller:

        //Only Device Ready Here
        document.addEventListener('deviceready', $scope.DeviceEvents.onDeviceReady, false);
        $scope.DeviceEvents={
            onDeviceReady: function(){
                //Register Device Events Here
                document.addEventListener('resume', $scope.DeviceEvents.onResume, false);
            },
            onResume:function(){
                alert("resuming!!!");
            }
        };

And again,

Failed!!!

Now, does any one knows how should i do it side by mobile-angular-ui? how to register any kinds of event inside the app, which come from device.

If i'm wrong any where, Sorry, I'm new to all of these stuff, Android, Cordova, and know the basic of Angular, ... someone who's boss told him to write an application, that i'm not familiar with any part of it.

Thank you, Hassan F.


Edit

I also find this just now, it been used withing the angular it self, but it still doesn't have any thing to do with the controller...

MyModule.run(function ($rootScope, $http, dataService, $window, $q, $location, localize) {

document.addEventListener("deviceready", onDeviceReady, false);

function onDeviceReady() {

//Initialize anything you need to. aka: Google analytics.

//Set other evens you need to listen to.
document.addEventListener("online", onOnline, false);
document.addEventListener("offline", onOffline, false);

} }

here's what i did... First, i remove the ng-app, from my HTML

then i register onDeviceReady event, and inside that, then i append ng-app to my html, so after device become ready, angular will start it's processes.

Second, i have multi-layered structure, which mean, i have a master page, which sit on HTML tag, and other controller are within this one, using ng-view and route config.

so i bind events to my master controller:

like this:

module RavisMobileCordova {

    export module Application {
        export function initialize() {

            var matchesDevice = navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry|IEMobile)/);

            isBrowser = !(matchesDevice!=null && matchesDevice.length > 0);

            document.addEventListener("deviceready", onDeviceReady, false);

            if (isBrowser) {
                // Create the event
                var event = new CustomEvent("deviceready", {});
                // Dispatch/Trigger/Fire the event
                document.dispatchEvent(event);
            }
        }

        function onDeviceReady(evt) {
            angular.element(document).ready(() => {
                var domElement = document.getElementById("appElement");
                angular.bootstrap(domElement, ["ravisMobileApp"]);
            });

            // Handle the Cordova pause and resume events
            //TRUE: Capture Phase, FALSE: Bubbling Phase
            document.addEventListener("pause", onPause, false);
            document.addEventListener("resume", onResume, false);
            document.addEventListener("backbutton", onBackButton, true);
            document.addEventListener("offline", onOffline, false);
            document.addEventListener("online", onOnline, false);
            // TODO: Cordova has been loaded. Perform any initialization that requires Cordova here.

            var scope:any = angular.element("[ng-controller='MasterController'], [data-ng-controller='MasterController']").scope();
            scope.SystemApi.Navigator = navigator;

            scope.SystemEvents.OnStart(evt);
        }

        function onPause() {
            // TODO: This application has been suspended. Save application state here.
        }

        function onResume() {
            // TODO: This application has been reactivated. Restore application state here.
        }

        function onBackButton(evt) {
            //evt.preventDefault();
            //evt.stopPropagation();
            var scope:any = angular.element("[ng-controller='MasterController'], [data-ng-controller='MasterController']").scope();
            scope.SystemEvents.BackButton(evt);
        }

        function onOffline() {
            var scope: any = angular.element("[ng-controller='MasterController'], [data-ng-controller='MasterController']").scope();
            scope.SystemEvents.OnOffline();
        }

        function onOnline() {
            var scope: any = angular.element("[ng-controller='MasterController'], [data-ng-controller='MasterController']").scope();
            scope.SystemEvents.OnOnline();
        }
    }

    window.onload = () => {
        Application.initialize();
    }
}

then i define this section within my master controller, which get called on registerd events...

    $scope.SystemEvents = {
        OnStart: function () {
            LocalStorageService.NavigatorHistory.clearHistory();

            angular.element("#master_overlay").removeAttr("style");

            if ($scope.SystemMethods.IsNetworkOffline()) {
                //$scope.SystemEvents.OnOffline();
                // Create the event
                var event = new CustomEvent("offline", {});
                // Dispatch/Trigger/Fire the event
                document.dispatchEvent(event);
            }
        },
        OnOnline: function () {
            if (!Utility.isNullOrUndefined(eventList[EventTypes.Online])) {
                for (var i = 0; i < eventList[EventTypes.Online].length; i++) {
                    eventList[EventTypes.Online][i].callBack();
                }
            }

            $scope.SystemMethods.HideMasterOverlay();
        },
        OnOffline: function() {
            if (!Utility.isNullOrUndefined(eventList[EventTypes.Offline])) {
                for (var i = 0; i < eventList[EventTypes.Offline].length; i++) {
                    eventList[EventTypes.Offline][i].callBack();
                }
            }

            $scope.SystemMethods.ShowMasterOverlay();
        },
        BackButton: function (evt) {
            //Bind Cancel
            evt.cancel = false;

            //Call All Registered Events
            if (!Utility.isNullOrUndefined(eventList[EventTypes.BackButton])) {
                for (var i = 0; i < eventList[EventTypes.BackButton].length; i++) {
                    eventList[EventTypes.BackButton][i].callBack(evt);
                }
            }

            //If Cancel Do Return
            if (evt.cancel)
                return;
            //TODO: API Cancelable Code Here
            $scope.SystemMethods.MoveToPreviousPage();
            //evt.preventDefault();
            //evt.stopPropagation();
        },
        HistoryBack: $scope.SystemMethods.MoveToPreviousPage
    };

now if i ever need these within my master page, i do what i need in here, else, if i need them in my other controllers... here's what i gonna do:

Master Controller:

var eventList = {};
$scope.SystemMethods = {
    RegisterEvent: function(eventType, callBack) {
        if (Utility.isNullOrUndefined(eventList[eventType]))
            eventList[eventType] = [];
            eventList[eventType].push({ eventType: eventType, callBack: callBack });
        },
        UnregisterEvent: function(eventType, callBack) {
        var delList = Enumerable.From(eventList[eventType]).Where(function (w) {
            return w.eventType === eventType && w.callBack === callBack;
        }).ToArray();
        for (var i = 0; i < delList.length; i++) {
            var objIndex = Enumerable.From(eventList[eventType]).IndexOf(delList[i]);
            eventList[eventType].splice(objIndex, 1);
         }
     }
}

Other controllers: You also have to unregister what you register, since your master controller is persist and you pass your function to the variable within that controller, they won't go away by their own selves $scope.initialize = function () { $scope.SystemMethods.RegisterEvent(EventTypes.BackButton, $scope.Events.backButton); $scope.SystemMethods.RegisterEvent(EventTypes.Online, $scope.Events.online); }

$scope.$on("$destroy", function () {
    $scope.SystemMethods.UnregisterEvent(EventTypes.Online, $scope.Events.online);
    $scope.SystemMethods.UnregisterEvent(EventTypes.BackButton, $scope.Events.backButton);
});

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