0

I'm trying to build an Angular app that consists of a fullscreen map and a sidebar.

I currently have a MapController that setups the map and then I have a PlacesController for listing places in the sidebar. If I now would like to add a marker to the map by clicking a link in the sidebar, how should this be handled?

My idea: The PlacesController have a function called addMarker that calls another function called addMarker in a service that broadcasts "addMarker" using "$rootScope.$broadcast('addMarker');" which the MapController listens for and then calls "addMarker" in the MapController which actually adds the marker to the map.

Is there an easier/better way of doing this?

gusjap
  • 2,397
  • 5
  • 24
  • 38
  • 2
    Move the code for working with maps to a service and use that service in both controllers. Your idea sounds really bad. – Nikolay Baluk Aug 30 '14 at 21:35

1 Answers1

2

You should have the data all contained in some service that notifies any listeners when it is changed. Edit Here is a jsBin demonstrating this method

The observer pattern would be good for this one:

app.factory('MapService', function() {
  var observerCallbacks = [];
  var markers = [];

  var publicMembers = {
    addMarker: addMarker,
    getMarkers: getMarkers,
    registerObserverCallback: registerObserverCallback
  }

  function addMarker (marker) {
     markers.push(marker);
     notifyObservers();
  };

  function getMarkers() {
     return markers;
  }

  function registerObserverCallback(callback){
    observerCallbacks.push(callback);
  };

  function notifyObservers(){
    angular.forEach(observerCallbacks, function(callback){
      callback();
    });
  };

  return publicMembers;
});

And then in your controller you can can inject this service, register as an observer, and any time observers are notified (e.g., in addMarker, your callback will be executed:

app.controller('MyController', function($scope, MapService) {
    MapService.registerObserverCallback(function() {
        $scope.markers = MapService.getMarkers();
    });
});
Tom
  • 7,640
  • 1
  • 23
  • 47