NgShow not reacting when switching between normal and full screen mode

47 views
Skip to first unread message

Bago Zonde

unread,
Jul 4, 2015, 6:30:00 PM7/4/15
to ang...@googlegroups.com
Hi all!

I want to display a button if no full screen mode set. I'm using screenfull library for this (https://github.com/sindresorhus/screenfull.js/).
It works perfectly using interval in JS - I can check if button should be displayed or not (in real code I have two buttons for entering / exiting full screen mode as toggle, but for this example I've simplified it to only one button).

I moved this implementation to AngularJS's (v1.3.9 and v1.4.1 tested) controller using ng-show directive and ng-show seems to works, but unfortunately not when I'm entering / exiting full screen mode but only when I'm changing a model (I will write about it in a moment). Note: I can exit full screen mode by pressing ESC or some button on a mobile phone, so I don't want to map every user's action. Ng-show should be a solution to check screen mode.

So, when I'm switching between screen modes - ng-show directive is "sleeping". If I will change something in model, then ng-show will react, but I will show some example on the end of this post, for now let's see how I've implemented that.

I set ng-show this way:

<button class="full-screen-mode" data-ng-show="!isFullScreen()"></button>

Clicking the button will enter to full screen mode:

$('.full-screen-mode').click(function() {
   if (screenfull.enabled) {
      screenfull
.request($('.wrapper')[0]);
   }
});

I'm injecting screenfull library as factory (I was trying also with injecting a service, but no luck either with final effect):

var screenfullLibraryApp = angular.module('screenfull', []);
screenfullLibraryApp
.factory('screenfull', function() {
   return screenfull;
});

var app = angular.module('app', ['screenfull']);

app
.controller('MainCtrl', ['$scope', 'screenfull', function ($scope, screenfull) {

   
var lastFullscreen = false; // just for test purposes...

    $scope
.isOk = function() {
       
return $scope.yourName === '1';
   
};

    $scope
.isFullScreen = function() {
       
if (screenfull.isFullscreen !== lastFullscreen) { // condition for test purposes...
            lastFullscreen
= screenfull.isFullScreen;
            console
.log('switch! ' + (lastFullscreen === true ? 'true' : 'false'));
       
}
       
return screenfull.isFullscreen === true;
   
};
}]);



So, this code won't work but I've noticed, that ng-show will actually react when I will change model, e.g. when I will enter some value to input like that:

<input type="text" data-ng-model="textField">

Then ng-show will switch this button and will output this: console.log('switch! ' + (lastFullscreen === true ? 'true' : 'false'));  that many times, I've clicked on full screen / exit full screen! So, it seems to work, but something's wrong with screenfull library injected as factory / service, or maybe this is some kind of AngularJS behaviour I have no knowledge about.

Please help me to understand, what I'm doing wrong?

Thanks in advance!

Bago Zonde

unread,
Jul 4, 2015, 6:42:18 PM7/4/15
to ang...@googlegroups.com
All right, problem solved :D however I don't understand how is AngularJS actually working this way.

In my code, function responsible for switching to full screen mode was a jQuery click method, so after moving also this part to AngularJS and adding ng-click directive to this button, everything reacts now properly. Possibly, model is updating this way immediately.

:)

Bago Zonde

unread,
Jul 4, 2015, 6:51:06 PM7/4/15
to ang...@googlegroups.com
Well, I think I've finally got it :).

Every ng-show will be executed when anything in controller will be changed, that's why my jQuery was not detected in AngularJS's controller, it's logic!

I found that I don't need even injecting this screenfull library here, as it's accessible globally.

Sander Elias

unread,
Jul 6, 2015, 9:40:48 AM7/6/15
to ang...@googlegroups.com
Hi Bago,

Angular's data binding works well within the realm of the angular app. If you fire off events/code outside, you need to tell angular that it needs to $digests the changes you made to the data. This is where you use $scope.$apply. However, often it is much simpler to just solve it by doing whatever you need to do inside your app. (as you figured out already!)

Regards
Sander

Bago Zonde

unread,
Jul 6, 2015, 11:34:34 AM7/6/15
to ang...@googlegroups.com
HI Elias,

I was trying to do $scope.$apply but it held my browser, maybe I was doing something wrong as I've added this to ng-show, not to ng-click. However about $apply I should go into details.
Well, it's better to keep all code in a controller so thanks for info, maybe I will use it someday :).

Sander Elias

unread,
Jul 7, 2015, 1:39:07 AM7/7/15
to ang...@googlegroups.com
Ho Bago,

Both ngShow and ngClick are already in the angualr realm, so doing a $scope.$apply in there is a bad idea. For example, you need one, if you use an native click event, or a jquery $('#someId').on('click', function () {doSOmething; need$scope$applyHere}). (or some other non-angular way to handle events...)

Regards
Sander
Reply all
Reply to author
Forward
0 new messages