I have a single page app that opens a gallery. I want to bind document level keyup event (for keyboard gallery controlls) only when the gallery is open, ie. when route matches
.when('/reference/:galleryId/:imageId/', { templateUrl: '/partials/gallery.htm', controller: 'galleryController', controllerAs: 'reference' })
and I want to unbind it when I leave this route.
One thing that might be a problem is, I block reloading the view between images within the same gallery with this:
.run(['$route', '$rootScope', '$location', function ($route, $rootScope, $location) {
var original = $location.path;
$location.path = function (path, reload) {
if (reload === false) {
var lastRoute = $route.current;
var un = $rootScope.$on('$locationChangeSuccess', function () {
$route.current = lastRoute;
un();
});
}
return original.apply($location, [path]);
};
}])
Demo (Click on "Fotografie" to open the gallery) http://tr.tomasreichmann.cz/
Angular wiz to the rescue?
Thank you for your time and effort
The ng-controller="myCtrl" attribute is an AngularJS directive. It defines a controller. The myCtrl function is a JavaScript function. AngularJS will invoke the controller with a $scope object.
The Scope in AngularJS is the binding part between HTML (view) and JavaScript (controller) and it is a built-in object. It contains application data and objects. It is available for both the view and the controller. It is an object with available properties and methods. There are two types of scopes in Angular JS.
All the AngularJS application mainly relies on the controllers to control the flow of data in that application. Basically, it controls the data of AngularJS applications and the controller is a Javascript object, created by a standard JavaScript object constructor.
You could bind a keyup event to $document
in your controller's constructor and then unbind the event when the controller's $scope
is destroyed. For example:
.controller('galleryController', function ($scope, $document) {
var galleryCtrl = this;
function keyupHandler(keyEvent) {
console.log('keyup', keyEvent);
galleryCtrl.keyUp(keyEvent);
$scope.$apply(); // remove this line if not need
}
$document.on('keyup', keyupHandler);
$scope.$on('$destroy', function () {
$document.off('keyup', keyupHandler);
});
...
});
There will be nothing left behind when the view become inactive.
If you feel it isn't right to do this in the controller, you could move this into a custom directive and place it in a template of the view.
Finally I stuck with
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:og="http://ogp.me/ns#"
xmlns:fb="http://www.facebook.com/2008/fbml"
lang="cz"
ng-app="profileApp"
ng-keyup="$broadcast('my:keyup', $event)" >
Not sure if this is good practice, but it registers within my controller
$scope.$on('my:keyup', function(event, keyEvent) {
console.log('keyup', keyEvent);
galleryCtrl.keyUp(keyEvent);
});
And doesn't do anything when the current route is not active
I found this answer here: https://groups.google.com/forum/#!searchin/angular/document$20level$20events/angular/vXqVOKcwA7M/RK29o3oT9GAJ
There is another way to bind it globally which wasn't my goal, the original code in question did what I needed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With