Ionic and Angular JS tips - 3esmit/zmNinja GitHub Wiki
A collection of various things I learned along the way. Of interest to new developers only.
-
Stop! Read all the links here: http://ionicframework.com/docs/overview/, specifically the CSS, Javascript and CLI links or you'll land up re-inventing the wheel
-
Use
ionic serve
to test your app right in the browser. Saves you a lot of time -
If you need to display ver large lists, don't be dismayed by browser performance. The fine folks @ ionic have a near native performance solution for that situation - instead of lists, use ionic collections. http://ionicframework.com/docs/api/directive/collectionRepeat/
-
You don't need to generate icons for all platforms. Just create a large enough splash and icon png and use
ionic resources
http://ionicframework.com/docs/cli/icon-splashscreen.html -
Don't load the HTML body till Angular initializes - if you do that, then the screen will jump around after the status bar shows up. To avoid that, don't tag your body with ng-app. Inject it after ionic is ready. For example, this is what I added at the end of my index.html
<script>
window.ionic.Platform.ready(function () {
console.log("******* PLATFORM READY ****");
angular.bootstrap(document, ['zmApp']);
});
</script>
-
If you need a side menu app, or a tab bar app etc, don't start from scratch. Use ionic templates https://github.com/driftyco
-
If you are looking at dynamic graphs, look at tc-chartjs & chartjs or google graphs. Both are great. I used D3 as well but had issues with it not refreshing/being responsive. I used nvd3. I finally settled with google charts - lots of options, but tc-chartjs was the easiest
-
Angular JS is heavily events based. You need to program to optimize fast loading views --> use promises ! understand them well!
-
Go easy on using route resolves --> I use them today only for a small http get. If you wait for too long, a view won't load and that is not good UX. Its better to load a view, show a loader and then load
-
I found this to be the most compatible way to capture orientation changes across platforms (I discovered ngCordova later -- maybe that offers a better mechanism)
window.onorientationchange = function () {
console.log("**ORIENTATION CHANGE**");
var pixelRatio = window.devicePixelRatio || 1;
$rootScope.devWidth = ((window.innerWidth > 0) ? window.innerWidth : screen.width);
$rootScope.devHeight = ((window.innerHeight > 0) ? window.innerHeight : screen.height);
console.log("********Computed Dev Width & Height as" + $rootScope.devWidth + "*" + $rootScope.devHeight);
}
-
Use services/ factories to share data between controllers. Makes your code more modular
-
If you are using state functions to block certain views on pre-conditions (example, you can't go to view X unless you log in), and are facing the odd "digest loop" problem, there seems to be a bug. This is what works:
in .config in app.js:
$urlRouterProvider.otherwise( function($injector, $location) {
var $state = $injector.get("$state");
$state.go("<your default state>");
});
And in your
$rootScope.$on('$stateChangeStart', function (event, toState, toParams) {
This:
event.preventDefault();
$state.transitionTo('login');
- Using config.xml to change splash screen timing doesn't work. Install ngCordova, change config.xml to always show the splash screen and then do this in app.run and specify your own timeout
.run(function ($ionicPlatform, $ionicPopup, $rootScope, $state, ZMDataModel,$cordovaSplashscreen) {
setTimeout(function() {
$cordovaSplashscreen.hide()
}, 5000)
- An easy way to call controller functions inside the HTML templates is simply to add that function to the $scope variable inside its controller. For example, for foo.html and controller fooCtrl.js, do this in fooCtrl.js:
$scope.generateChart = function (chartTitle) {
<whatever>
}
and in your foo.html
{{generateChart('All Events')}}
BE CAREFUL: if you are updating scope elements for display this can easily get into a digest loop and crash
-
If you want to add pinch and zoom to images, it's as simple as adding the
directive to your container - and set has-bouncing to false to remove the web page look
-
Use Angular directives to trap image loading scenarios so you can add text to avoid empty screens when loading Example:
<img imageonload="finishedLoadingImage()" ng-src="{{LoginData.url}}/cgi-bin/zms?mode=jpeg&monitor={{monitorId}}&maxfps=3&buffer=1000&user={{LoginData.username}}&pass={{LoginData.password}}&rand={{rand}}" width="100%" />
And the directive in app.js
.directive('imageonload', function() {
return {
restrict: 'A',
link: function(scope, element, attrs) {
element.bind('load', function() {
//call the function that was passed
scope.$apply(attrs.imageonload);
});
},
};
})
-
On Android, please use crosswalk - blazing fast performance compared to the native android browser http://blog.ionic.io/crosswalk-comes-to-ionic/ --> It basically bundles a high perf. Chrome browser with the app
-
Chrome has a problem with multiple http sockets that don't close - typically the case with dynamic img src urls. iOS handles it perfectly. The solution is not to use img src with dynamic images being pushed. Grab a frame and write a $interval to refresh that img-src https://github.com/arjunroychowdhury/zmNinja/issues/7
-
If you need to navigate to external links and don't want to mess up your app's web view,
cordova plugin add cordova-plugin-inappbrowser
and then
<ion-item>
<h2><b>I want to contribute!</b></h2>
Awesome. <a href="#" onclick="window.open('http://github.com/arjunroychowdhury/zmNinja', '_blank', 'location=yes'); return false;"> Grab</a> the source code!
</ion-item>
-
If you need to implement pagination while scrolling, don't re-invent the wheel. ion-collection plus ionic-infinite-scroll offers blazing fast performance!
-
Chrome (as of today) has a problem if you open too many HTTP/TCP streams that stay open for a long time. This puts HTTP requests into pending state and it never recovers till you restart the app. The work around is to close TCP connections soon: https://code.google.com/p/chromium/issues/detail?id=234779
-
If you need date arithmetic and don't want to deal with the vagaries of browser specific issues, just use http://momentjs.com. Here is how simple it is to do date math:
var cur = moment();
endDate = cur.format("YYYY-MM-DD hh:mm:ss");
startDate = cur.subtract(hrs, 'hours').format("YYYY-MM-DD hh:mm:ss");
- Use the cordova keyboard plugin - adjustments/hiding/scroll-bouncing are better with it
cordova plugin add com.ionic.keyboard