Category Archives: Angular

Bootstrapping Angular in Cordova

16 Oct 2015

Creating hybrid apps means almost all of your time is spent in Chrome doing layout, development, testing, etc. When it comes time to start integrating your app into PhoneGap/Cordova you have to take into account a device’s deviceready event but doing so breaks your app outside of the Cordova wrapper.

One option is to automate your builds using Gulp. If you’re adverse to this you can try the following bit of code which will allow you to easily switch from your desktop to device:

        ;(function(){
            function bootstrapNG(){
                angular.bootstrap(document.querySelector('html'), ['name-of-your-app']);
            }
            if (document.location.href.indexOf('http') === -1){
                document.addEventListener('deviceready', function(){
                    angular.element(document).ready(bootstrapNG);
                }, false);
            } else {
                angular.element(document).ready(bootstrapNG);
            }
        })();

This works because the assumption is that as a dev you will be running a local server to run your app whereas in Cordova/Phonegap the app is running directly off of the file system so that URL is not using an HTTP:// scheme but is instead using file://.

Note that manually bootstrapping Angular will require you to remove the ng-app directive from your page.

Angular and Scrolling Content

15 Oct 2015

I’m currently enrolled at Thinkful.com in the Angular course. I’m well over half-way through and have been applying Angular to my work projects with great success. One thing that I needed to do was to have scrolling views in my hybrid apps while having other areas of the app remain static. My future goals involve using Ionic – which handles scrolling easily enough, and I suspect, in the exact same way I’ve done it here – but I’m a logical step-by-step kind of guy so for now I’m content with learning Angular and rolling my own UI. That being the case I thought to search for the “Angular” way of getting views to scroll and tried a few of the custom directives available on the Internet.

The easiest to set up was ng-scrollable which technically worked but lacked the finesse of the vaunted iScroll. I also tried angular-iscroll but without much success. I reverted to the usually reliable iScroll but Angular didn’t want to play nicely with it. I then reverted to ng-scrollable thinking I could revisit it and proceeded with my other layout duties only to find that ng-scrollable injected too much crap into the DOM which broke a previously working flex-box-based layout. Attempts to rectify the layout proved to be a waste of time. So, I removed ng-scrollable and instead pursued a native / pure css solution.

The Technique

So lets get back to what I wanted – native-like smooth scrolling with inertia. The answer can be found via CSS by creating a class with the following properties (your wrapping container must have a set width / height, and a setting of “overflow:hidden” on the wrapper will kill scrolling):

.scrollable {
    overflow-x: hidden; // Control how to clip the container's content.
    overflow-y: scroll;
    -ms-overflow-style: -ms-autohiding-scrollbar; // configure overflow scrolling behavior for IE 10
    -webkit-overflow-scrolling: touch; // The magic happens here
}

Each of the above styles are configured as follows:

  • -webkit-overflow-scrolling
    • auto – Non-inertia scrolling. Scrolling stops as soon as your finger no longer touches the screen.
    • touch – Use inertia-based scrolling, the faster you flick the scrollable content the faster it scrolls but continues to a deaccelration scroll whne your finger stops touching the screen. I find this to be the desired behavior as its closest to native on Mobile.
  • overflow-x, overflow-y – These properties specify how to treat overflowing content via one of the following values:

    • visible – Indicates the content is not clipped, it may be rendered outside the content box.
    • hidden – Indicates the content is clipped and no scrollbars are provided.
    • scroll – Indicates the content is clipped and desktop browsers use scrollbars whether or not any content is clipped. For hybrid application development the scrolling behavior mimics native scrolling where scroll bars don’t appear unless you interact with the scrollable content. On Android at least the scrollbar overlaps content so you should add padding to account for it. On desktop the scrollbars use up additional space within the scrolling wrapper.
    • auto – Depends on the user agent – meaning that you should expect the native behavor for the overflowing content.

I’m not too concerned with IE in my hybrid app development but here are the configuration options none-the-less:

  • -ms-overflow-style – Sets the scrolling behavior for overflowing elements in IE (copied from MS).

    • auto – Indicates the element inherits its -ms-overflow-style from its parent element
    • none – Indicates the element does not display scrollbars or panning indicators, even when its content overflows. Unlike overflow: hidden, elements with -ms-overflow-style: none can still be scrolled via touch panning, keyboard, or mouse wheel.
    • scrollbar – Indicates the element displays a classic scrollbar-type control when its content overflows.
    • -ms-autohiding-scrollbar – Indicates the element displays auto-hiding scrollbars during mouse interactions and panning indicators during touch and keyboard interactions.

Notes

If using this on Android / PhoneGap be sure to install the Crosswalk plugin so that you don’t have to worry about compatibility with older webkits.

Also, it is worth noting that sometimes it wont work unless you apply the webkit-specific styling directly to the element like so:

<div id="comeContent" style="-webkit-ovrflow-scrolling: touch;">...

Also worth noting is that if the content of the scrolling element changes that you may need to force the content heights to be recalculate on iOS by inserting a psuedo-element using a simple calc() function to determine its new height:

#comeContent:before {
  content:'';
  width: 1px;
  float: left; // remove from the document flow
  height: calc(100% + 1px); // force the recalculation of the container's height
  margin-left: -1px; // remove from view
}

Other methods of forcing a screen redraw may work as well.