JQuery-Mobile with AngularJS and Angular-Route (ngRoute)

Introduction

The following details how JQuery-Mobile and AngularJS can play together seamlessly. Angular-Route (ngRoute) is used for navigation. A simple Angular directive invokes JQuery-Mobile styling and enhancements as each page is loaded. This includes pages loaded via  ng-include

A working example is available here as a Plunker http://plnkr.co/edit/RPbJfWX84XkzWlvPFMvX?p=info

Highlights

Routing

Angular-Route performs all navigation. JQuery-Mobile’s navigation is turned off. As per the JQuery-Mobile documentation here #Hash-URL-listening is turned off along with link-binding. Now JQuery-Mobile will not respond to #hash URL changes, it will also not respond to link click events. Both of these features are now handled by AngularJS ngRoute.

Binding

The jqm  directive responds to the presence (or arrival to be more accurate) of any element with attribute jqm  by invoking element.trigger('create');  immediately after AngularJS is finished binding. Angular’s $timeout  is used to wait until after Angular has finished rendering/binding before .trigger(‘create’) is invoked. Note the wait time may need to be increased if necessary.

This technique allows for content to be dynamically added to the DOM with JQuery-Mobile styling etc taken care of automatically.

For example

ngInclude  is used in “ create.html ” and “ edit.html “. The contents to be included, i.e. “ form.html ” has the jqm  attribute so it too is subject to the directive which applies JQuery-Mobile styling once AngularJS has finished rendering/binding.

<div ng-include="'form.html'"></div>

jqm Directive

Application Example

The demo application at http://plnkr.co/edit/RPbJfWX84XkzWlvPFMvX?p=info is a very basic CRUD simulation. Even the AJAX calls are simulated.

There is an array of “person” objects, “personArray”, which is displayed initially as a list in “ list.html “. The application allows for viewing a person, editing a person and deleting a person.

AJAX

There is no AJAX in the application but AJAX calls are simulated using setTimeout. This is simply to demonstrate how binding and rendering would apply in an AJAX environment.

The only notable point on this is in the listController . $('ul.ngRepeat').listview('refresh');  is required to redraw the list after binding. This is not an AngularJS Vs. JQuery-Mobile quirk or some limitation of using Angular with JQuery-Mobile. It is a feature of JQuery-Mobile. It is something that simply must be done when using JQuery-Mobile with JSON/AJAX.

The application is hosted on Plunker http://plnkr.co/edit/RPbJfWX84XkzWlvPFMvX?p=info The inspiration for the solution comes from this Plunker http://plnkr.co/edit/dThXNX?p=preview by http://plnkr.co/users/caiotoon

Conclusion

A means of integrating JQuery-Mobile with AnguarJS and Angular-Route has been demonstrated. A worked example is available on Plunker here.

Navigation responsibility is taken from JQuery-Mobile and delegated to ngRoute. This could generally be considered advantageous.

A reusable angular directive to integrate the two has been provided. This directive needs no modification to work (consider $timeout  wait time if issues arise), it simply sits in the background and executes to apply JQuery-Mobile styling after angular has bound/rendered following each page load event.

Comments, questions and critique always welcome.

Reference

Plunker http://plnkr.co/edit/dThXNX?p=preview by http://plnkr.co/users/caiotoon

 

7 Comments

  • Hi John, thank you very much for this.

    I’ve been using jquery mobile for a while and not happy with my current js architecture.. I’m not too familiar with angularjs but this seems to be a great way to do this.

    I am trying to understand, it seems that all of the controllers, when initiated by the router, populate their templates into the near the bottom of index.html

    Where is the logic that specifies the templates to render there? The div does not have a name to be referenced, and I dont understand what causes the templates to render there specifically.

    Thanks in advance!

    • Hi Chris

      Thanks for the comment. Simple answer is: That’s just the way things are with Angular or specifically ngRoute.

      The $routeProvider stuff in config.js assigns a controller to a page. The page contents will pop into that ng-view div asynchronously. This functionality comes out of the box from ngRoute which is an additional feature for angularJs for building single-page-applications.

      As you’re not too familiar with AngularJS, you’re in for a real treat. It’s an amazing framework/methodology. I’ve a bunch of tutorials here which can help get you going: http://outbottle.com/category/angularjs/ I’d suggest dedicating some time (two to three hours) to learning it, it’s surprisingly easy to get started with. Try https://egghead.io/technologies/angularjs for some quick starter video tutorials.

      After you get the basics going, google ngRoute for a few tutorials on that. As mentioned, it’s an additional addon to AngulaurJS which makes light work of single page applications (which in my opinion is best way to build not just mobile apps but any modern web apps). ngRoute equates to just some simple configuration code used with a div with an attribute ng-view to slot in pages asynchronously and automatically.

      The configuration in this blog/tutorial lets angularjs ngRoute take care of navigation, the JQM navigation stuff is turned off.

      Feel perfectly free to pop more questions here.

      John

  • John,
    I found your article after hitting a snag with… of course… jQuery Mobile and Angular.

    Thank you for sharing this article and code! I have been working on building out a mobile app with DevExtreme and debated about using DevX routing vs. Angular. I wanted to go with Angular so that I have a more diverse skill set vs. using DevX. I have experience with MVC.NET so I was more inclined to use Angular. After reading your article I am now for sure going tow Angular.

    I posted a link back to this article on my blog under “Tips and Tricks”

    Thank you ! !

    • Hi Daniel

      I’m sure you can yes. As in, one or the other, jqm transitions or ngRoute. Obviously they can’t work together. NgRoute has many advantages, friendly URLs (if needed) plus association of a controller with a page, service injection etc. It would probably be more difficult and cumbersome to use jqm transitions.

      Let me know what you think.

      John

  • I used your techniques to convert an app I am working on from Bootstrap to jQuery Mobile yesterday. I’m sure I would not have figured out the secrets myself. Thanks.