Slide used in the HTML5 CodeShow Roma #9.
The talk covers basic Maps API following by the use of AngularJS to create a Maps application. The source code for live demo can be found under the "demo" directory in the github repository.
6. Let’s Talk About Maps
Google Maps
OpenStreetMap
Apple Maps
Yahoo! Maps
Bing Maps
Nokia Here
..
http://en.wikipedia.org/wiki/Comparison_of_web_map_services
34. BaseGoogleMap
.factory('BaseGoogleMap', function (…) {
var MapObject = function () { … };
MapObject.prototype = {
initMap: function (mapId) { … };
initSearchBox: function (inputId) { … };
};
return MapObject;
});
.factory(‘GoogleMap’, function (BaseGoogleMap) {
return new BaseGoogleMap();
});
.factory(‘HybridMap’, function (BaseGoogleMap) {
var gmap = new BaseGoogleMap();
gmap.initMap = function (mapId) { … };
return gmap;
});
35. AngularJS Promise
.service('OpenStreetMap', function ($http, $q) {
this.search = function (query) {
var url = “http://…” + query, d = $q.defer();
$http.get(url,
function (response) {
// Update map with data from response
d.resolve(response);
},
function (error) { d.reject(error); }
);
return d.promise;
};
});
OpenStreetMap.search(“Via del Corso”).then(function (data) {
// data is the same response object passed by $d.resolve
});
// Use Promise in Controller
Per quelli che non mi conosci, “Pardon my Italian”
In this talk, I will:
A very quick walk through how to use the Maps
How I converted a Map application to AngularJS
Simple demo throughout the talk to illustrate the key concepts
Sono un Startupper lavorando su progetto EnergyCar che sara catalizzatore per le il mercato delle macchine elettriche, dando la possibilita a persone che non ha il box a carrigare il loro machine electrique
Sono uno dei manager di comunita Code Invaders e me trove su il nosso Google+ community
E svillupatore AngularJS. Ho creato “angularAMD”, pacchetto open source per rendere piu facile il uso de RequireJS con AngularJS.
So, a quick recap the app:
three links
a Geolocation button and config
A search section
and finally, the map
2 problems:
I wanted to use ngRoute to make this more Angular like, but…
Creating a map on every route change creates memory leak
There is a lot of work involved in destroy the map instance, and still potential memory leak
A quick review on what is AngularJS. It starts with ngApp, created using angular.module
Highlight the 3 key areas: Providers (in blue), Controller (in Black) and Views (in green)
Base on these 3 key areas, here is what I came up with
Quickly re-show the 3 key areas:
Providers (in blue),
Controller (in Black)
and Views (in green).
Controller and Views are combined by Router, except for MapController, which stays the same regardless of the route chosen.
Detail to be discussed later next few slides
The div that holds the map is coded in index.html
the input boxes on the other hand, is coded inside a view.
Notice how the mapfs.OpenStreetMap_class is used in both index.html and map.html
This is done at very beginning of the app, under app.js
Notice that MapController is set as parent controller.
When you have nested controllers, $scope of child controller is prototype inherited from the parent
Note that if mapfs is set in child controller, it can override the parent version.
BaseGoogleMap is base class for both GoogleMap and HybridMap as they share much of the code in common except the .initMap method
OpenStreetMap on the other hand, does not really share anything in common with BaseGoogleMap hence not using created from a Base Class
DefaultConfig are constants, meaning that changing it in module does not impact it’s value in another
MapUtil contains the logic for Geolocation
Notice the use of .prototype in BaseGoogleMap as 2 instances is going to be created.
In HybridMap, the .initMap is simple overridden so that Google map would use tiles from OpenStreetMap
Remeber that all AngularJS provider are Singleton.
A typical thing to do in a Provider is to access data from external source.
Promise is used in the AJAX call to OpenStreetMap when search for address.
However, in this case, I wanted to keep all Map related code, such as creation of the marker and POI, in the OpenStreetMap service.
The AJAX response needs to be returned as controller need to display the return address in the view. This is a simplified version of the real code.
Please note AngularJS’ $http already return a promise normally you would just return the $http.get() object.
As you can see, the Plain JS is tightly coupled with DOM, where code are implemented based on element that exists in htmls
Angular, on the other hands, the flow is much more top down, from Providers down to rendered view
Why? Basically, AngularJS achieve loose coupling between Controller and View using:
1. $scope that establishes two way binding
2. Dependency Injection Pattern of Providers (controllers, factory, service, etc) without polluting the Global namespace.
The result are:
Separation of concern as per MVC pattern, segregating your data logic in Models and your display logic in Views, resulting in code that is easier to read and thus maintain
Encourage the re-use of Provider created. OpenStreetMap in my example can be easily copied into another project without any modification.
Unit Testing -- Topic for a future talk
Other notable differences are:
Support of $routeProvider instead of MapSwitcherViewController with a simpler way to switch views
Consistent use of Promises that removes the ugly and confusion multi-level callback
Wrapper around common DOM methods such as $log, $timeout, $window to further decouple your code from DOM.