Skip to content

Commit

Permalink
Add gmShapesUpdate event to manually trigger element update.
Browse files Browse the repository at this point in the history
  • Loading branch information
dylanfprice committed Dec 17, 2013
1 parent e432593 commit 32a36bc
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 18 deletions.
34 changes: 29 additions & 5 deletions src/directives/gmMarkers.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,17 @@
* To use, you specify an array of custom objects and tell the directive how to
* extract an id and position from them. A marker will be created for each of
* your objects. If you assign a new array to your scope variable or change the
* array's length, the markers will also update.
* array's length (i.e. add or remove an object), the markers will also update.
* The one case where `gmMarkers` can not automatically detect changes to your
* objects is when you mutate objects in the array. To inform the directive of
* such changes, see the `gmMarkersUpdate` event below.
*
* Only the `gm-objects`, `gm-id` and `gm-position` attributes are required.
*
* @param {expression} gm-objects an array of objects in the current scope.
* These can be any objects you wish to attach to markers, the only requirement
* is that they have a uniform method of accessing an id and a position.
*
*
* @param {expression} gm-id an angular expression that given an object from
* `gm-objects`, evaluates to a unique identifier for that object. Your object
* can be accessed through the variable `object`. See `gm-position` below for
Expand Down Expand Up @@ -86,18 +88,40 @@
* 'position_changed', write it as 'gm-on-position-changed'.
*/

/**
* @ngdoc event
* @name angulargm.directive:gmMarkers#gmMarkersUpdate
* @eventOf angulargm.directive:gmMarkers
* @eventType listen on current gmMarkers scope
*
* @description Manually tell the `gmMarkers` directive to update the markers.
* This is useful to tell the directive when an object from `gm-objects` is
* mutated--`gmMarkers` can not pick up on such changes automatically.
*
* @param {string} objects Not required. The name of the scope variable which
* holds the objects to update markers for, i.e. what you set `gm-objects` to.
* It is useful because there may be multiple instances of the `gmMarkers`
* directive. If not specified, all instances of `gmMarkers` which are child
* scopes will update their markers.
*
* @example
* ```js
* $scope.$broadcast('gmMarkersUpdate', 'myObjects');
* ```
*/

/**
* @ngdoc event
* @name angulargm.directive:gmMarkers#gmMarkersRedraw
* @eventOf angulargm.directive:gmMarkers
* @eventType listen on current gmMarkers scope
*
* @description Force the gmMarkers directive to clear and redraw all markers.
* @description Force the `gmMarkers` directive to clear and redraw all markers.
*
* @param {string} objects Not required. The name of the scope variable which
* holds the objects to redraw markers for, i.e. what you set `gm-objects` to.
* It is useful because there may be multiple instances of the `gmMarkers`
* directive. If not specified, all instances of gmMarkers which are child
* directive. If not specified, all instances of `gmMarkers` which are child
* scopes will redraw their markers.
*
* @example
Expand All @@ -115,7 +139,7 @@
* @description Emitted when markers are updated.
*
* @param {string} objects the name of the scope variable which holds the
* objects the gmMarkers directive was constructed with. This is what
* objects the `gmMarkers` directive was constructed with. This is what
* `gm-objects` was set to.
*
* @example
Expand Down
28 changes: 26 additions & 2 deletions src/directives/gmPolylines.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,17 @@
* To use, you specify an array of custom objects and tell the directive how to
* extract location data from them. A polyline will be created for each of your
* objects. If you assign a new array to your scope variable or change the
* array's length, the polylines will also update.
* array's length, the polylines will also update. The one case where
* `gmPolylines` can not automatically detect changes to your objects is when
* you mutate objects in the array. To inform the directive of such changes,
* see the `gmPolylinesUpdate` event below.
*
* Only the `gm-objects`, `gm-id` and `gm-path` attributes are required.
*
* @param {expression} gm-objects an array of objects in the current scope.
* These can be any objects you wish to attach to polylines, the only requirement
* is that they have a uniform method of accessing an id and a path.
*
*
* @param {expression} gm-path an angular expression that given an object
* from `gm-objects`, evaluates to an array of objects with lat and lng
* properties. Your object can be accessed through the variable `object`. For
Expand Down Expand Up @@ -78,6 +80,28 @@
* 'position_changed', write it as 'gm-on-position-changed'.
*/

/**
* @ngdoc event
* @name angulargm.directive:gmPolylines#gmPolylinesUpdate
* @eventOf angulargm.directive:gmPolylines
* @eventType listen on current gmPolylines scope
*
* @description Manually tell the `gmPolylines` directive to update the polylines.
* This is useful to tell the directive when an object from `gm-objects` is
* mutated--`gmPolylines` can not pick up on such changes automatically.
*
* @param {string} objects Not required. The name of the scope variable which
* holds the objects to update polylines for, i.e. what you set `gm-objects` to.
* It is useful because there may be multiple instances of the `gmPolylines`
* directive. If not specified, all instances of `gmPolylines` which are child
* scopes will update their polylines.
*
* @example
* ```js
* $scope.$broadcast('gmPolylinesUpdate', 'myObjects');
* ```
*/

/**
* @ngdoc event
* @name angulargm.directive:gmPolylines#gmPolylinesRedraw
Expand Down
20 changes: 14 additions & 6 deletions src/services/angulargmShape.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,16 @@
*/
function _addNewElements(type, scope, controller, handlers, objectCache, optionsFn) {
angular.forEach(objectCache, function(object, id) {
var elementExists = controller.hasElement(type, scope.$id, id);
var element = controller.getElement(type, scope.$id, id);

if (!elementExists) {
var options = optionsFn(object);
if (options == null) {
return;
}
var options = optionsFn(object);
if (options == null) {
return;
}

if (element) {
controller.updateElement(type, scope.$id, id, options);
} else {
controller.addElement(type, scope.$id, id, options);
var element = controller.getElement(type, scope.$id, id);

Expand Down Expand Up @@ -141,6 +143,12 @@
updateElements(scope, scope.gmObjects());
}
});

scope.$on(_formatEventName('gmShapesUpdate', type), function(event, objectsName) {
if (objectsName == null || objectsName === attrs.gmObjects) {
updateElements(scope, scope.gmObjects());
}
});
}

/**
Expand Down
42 changes: 37 additions & 5 deletions test/unit/directives/gmMarkersSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ describe('gmMarkers', function() {

mapCtrl = elm.controller('gmMap');
spyOn(mapCtrl, 'addElement').andCallThrough();
spyOn(mapCtrl, 'updateElement').andCallThrough();
spyOn(mapCtrl, 'removeElement').andCallThrough();
spyOn(mapCtrl, 'trigger').andCallThrough();
spyOn(mapCtrl, 'addListener').andCallThrough();
Expand Down Expand Up @@ -142,7 +143,7 @@ describe('gmMarkers', function() {
it('updates markers with removed objects', function() {
var person = scope.people.pop();
scope.$digest();
var position = new google.maps.LatLng(person.lat, person.lng);
var position = objToLatLng(person);
expect(mapCtrl.removeElement).toHaveBeenCalledWith('marker', markersScopeId, '3');
});

Expand All @@ -155,6 +156,17 @@ describe('gmMarkers', function() {
});


it('updates markers with changed objects when update triggered', function() {
var person = scope.people[0]
person.lat = person.lat + 5;
person.lng = person.lng + 5;
var newPosition = objToLatLng(person);
scope.$broadcast('gmMarkersUpdate', 'people');
expect(mapCtrl.updateElement).toHaveBeenCalledWith('marker', markersScopeId,
jasmine.any(String), {key: 'value', title: jasmine.any(String), position: newPosition});
});


it('does not add null objects', function() {
var origLength = scope.people.length;
scope.people.push(null);
Expand All @@ -175,7 +187,7 @@ describe('gmMarkers', function() {

it('triggers events', function() {
var person = scope.people[0];
var position = new google.maps.LatLng(person.lat, person.lng);
var position = objToLatLng(person);
var id = person.name
scope.markerEvents = [{
event: 'click',
Expand All @@ -192,8 +204,9 @@ describe('gmMarkers', function() {


it('triggers events on multiple markers', function() {
var position0 = new google.maps.LatLng(scope.people[0].lat, scope.people[0].lng);
var position1 = new google.maps.LatLng(scope.people[1].lat, scope.people[1].lng);

var position0 = objToLatLng(scope.people[0]);
var position1 = objToLatLng(scope.people[1]);
var id0 = scope.people[0].name
var id1 = scope.people[1].name
scope.markerEvents = [{
Expand All @@ -210,7 +223,7 @@ describe('gmMarkers', function() {


it('triggers multiple events on markers', function() {
var position = new google.maps.LatLng(scope.people[0].lat, scope.people[0].lng);
var position = objToLatLng(scope.people[0]);
var id = scope.people[0].name
scope.markerEvents = [
{
Expand Down Expand Up @@ -308,6 +321,25 @@ describe('gmMarkers', function() {
{key: 'differentValue', title: jasmine.any(String), id: jasmine.any(String), position: jasmine.any(Object)});
});


it('listens for marker update event', function() {
var position1 = objToLatLng(scope.people[0]);
var position2 = objToLatLng(scope.people[1]);
scope.getOpts = function(person) {
return {
key: 'differentValue',
title: person.name
};
};
scope.$broadcast('gmMarkersUpdate', 'people');

expect(mapCtrl.updateElement).toHaveBeenCalledWith('marker', markersScopeId,
jasmine.any(String), {key: 'differentValue', title: jasmine.any(String), position: position1});
expect(mapCtrl.updateElement).toHaveBeenCalledWith('marker', markersScopeId,
jasmine.any(String), {key: 'differentValue', title: jasmine.any(String), position: position2});
});


it('emits marker update event when markers updated', function() {
var count = 0;
scope.$on('gmMarkersUpdated', function(event, objects) {
Expand Down

0 comments on commit 32a36bc

Please sign in to comment.