Handling map objet events through a wrapper

2,491 views
Skip to first unread message

Andre Tannus

unread,
Oct 30, 2010, 8:53:01 AM10/30/10
to google-map...@googlegroups.com
Hi guys, this is my first post.

I'm relatively new to javascript.

I'm designing a javascript interface in JS, and I'm using a lot of Google Maps (henceforth GM) in it; My tackles at it might sound confusing, because I am somewhat confused, so please, bare with me.

In my app, I decided to wrap the GM objects inside my own. For instance, I have a "shape" object which aggregates either a polyline or a polygon object - for the sake of simplicity, let's go with polygon, so, for a very simplified example to my problem.

// My Polygon "class"
myPolyClass = function(map) {
  this.path = [];
  this.map = map;
  this.poly = new google.maps.Polygon({ /*config*/|});
  
  this.setPath = function(path) {
    this.poly.setPaths(path);
  }

  google.maps.event.addListener(this.poly, 'click', function (event) {
    clickedInstance = this;
    clickedInstance.setPath([]);
  });

}

// myPoly instance
myPoly = new myPolyClass(map);

The problem is handling events on the polygon. When I click the polygon on the map, (which in this example makes it go away), the GM Polygon object fires the event (not my wrapper intance!).

The question: How to I bubble the event outwards, when the GM object isn't aware that it is within a wrapper?

I see two ways around it:

1. Make the app aware of the wrapper-object relationship. That would require creating a registry like object, that knows which of my objects own which GM object. Then the GM object fires a custom event that the registry is listening to, and the registry triggers the appropriate wrapper event. 

2. Make the GM object aware of the Wrapper object, and trigger it directly. Well, in that case, I could just go on and USE the GM object directly, and append my custom properties to it (which is precisely what I'm trying to avoid)

3. _______________________________________________________________________

eventually 4. ____, 5. ______

I hope you guys can shine light on my troubled mind. 

thank you in advance,

André

Ben Appleton

unread,
Oct 30, 2010, 9:04:37 PM10/30/10
to google-map...@googlegroups.com

Make the Wrapper object listen to the GM object and retrigger all events on the Wrapper.  For example:

function Shape() {
  this.shape_ = new google.maps.Polygon(...);
  var self = this;
  google.maps.event.addListener(
      this.shape_, 'click', function(e) {
    google.maps.event.trigger(self, 'click', e);
  });
  ...
}

- Ben

Android brevity.

> --
> You received this message because you are subscribed to the Google Groups "Google Maps JavaScript API v3" group.
> To post to this group, send email to google-map...@googlegroups.com.
> To unsubscribe from this group, send email to google-maps-js-a...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/google-maps-js-api-v3?hl=en.
>

Andre Tannus

unread,
Oct 31, 2010, 12:18:06 AM10/31/10
to google-map...@googlegroups.com
Hey ben, just got your reply.

I took the registry path, but I'm glad you answered! The registry idea is working fine, with the added advantage that I can use it to implement a bunch of other methods to manage the multiple shapes around the place.

roberto.cr

unread,
Oct 31, 2010, 11:24:51 AM10/31/10
to Google Maps JavaScript API v3
the registry idea is non-obstrusive, it's great to know it's working
fine.
I just don't know why there's a need to create your own "myPolyClass"
in the first place.

ps: I believe we met in gddbr =`] lets continue the chat in msn/gtalk
rober...@gmail.com

Andre Tannus

unread,
Oct 31, 2010, 12:11:50 PM10/31/10
to google-map...@googlegroups.com
I don't want to append my own properties to the GM objects and run the risk of google employees using the same prop name in the future, and have to deal with collision. Also, by wrapping the GM objects, I'm able to provide interfaces to GM objects, and, in the future, make the app "Map Agnostic", if you will.

But, like I said in the original post, I'm kind of new to JS. It keeps kicking me in the head, but I'm developing a rather exotic taste for it. It's freakishly flexible, plus, combined with the Closure Library, it's like playing with clay.

Either way, I hope I answered your question, and if I'm off the tracks (which is likely), by all means, let me know!

Who where you, at GDDBR? I didn't talk to that many people, so it won't be hard to remember!

Ben Appleton

unread,
Oct 31, 2010, 7:35:04 PM10/31/10
to google-map...@googlegroups.com
It sounds like you're using the Closure Compiler, and you're concerned
that your code's obfuscated properties will collide with GM compiled
properties. Property collision is not usually a problem, but there are
a few cases to watch out:

1 - You're subclassing/extending GM objects. We don't recommend that
precisely to avoid property collisions. Instead we recommend
composing objects: for example a Shape object could contain a
google.maps.Polygon object rather than extending google.maps.Polygon.

2 - You're extending the JavaScript Object or Array prototypes. We
don't recommend you do that, to avoid property collisions.

3 - You're setting properties on GM objects. In that case you want to
avoid obfuscation. For example:

--- Bad ---
var polygon = new google.maps.Polygon(...);
polygon.myId = 5; // For later identification in an event handler
------

--- Good ---
var polygon = new google.maps.Polygon(...);
polygon['myId'] = 5; // For later identification in an event handler
------

In the "bad" code, .myId may be obfuscated to collide with an
obfuscated property of google.maps.Polygon. In the "good" code, the
Closure Compiler will not obfuscate 'myId', so it will not
accidentally collide with obfuscated API properties.

- Ben

Andre Tannus

unread,
Oct 31, 2010, 8:23:06 PM10/31/10
to google-map...@googlegroups.com
Great pointers, thanks a bunch!

Michael Bolin mentions that in his book (which I strongly recommend by the way, if anyone else is interested). Apparently, the Closure Compiler will consider a literal property name (declared with an array-like notation) as something the developer doesn't want to have optimized/obfuscated.

There are indeed cases in which I need to append properties to GM objects, particularly when __gm_id doesn't cut it or when I need to create in the GM object an awareness of the soundings (the wrapper for instance), so

shape = new CustomShape( /* constructor provides a CustomShape.id*/ );
shape.poly = new google.maps.Polygon(...);
shape.poly['parentId'] = shape.id;

or something in this line. Of course the second and third lines happen within the constructor, but I'm lazy to fix that now.

Do you think using the __gm_id property has any serious disadvantages other than not having the guarantee that it'll the same the next time 'round, when I F5 the app?

Also, what's the deal with the messed up events? Why are some events simple objects with just lat/long, and others are more complex dom events, with a long property chain and stuff like event.responseValue, yadda yadda? Why aren't all events triggered in the map following the same pattern?

Should I move this question to a different (perhaps a new) post?

Thank you!!!

Ben Appleton

unread,
Oct 31, 2010, 11:37:56 PM10/31/10
to google-map...@googlegroups.com
On Mon, Nov 1, 2010 at 11:23 AM, Andre Tannus <andre....@gmail.com> wrote:
Great pointers, thanks a bunch!

Michael Bolin mentions that in his book (which I strongly recommend by the way, if anyone else is interested). Apparently, the Closure Compiler will consider a literal property name (declared with an array-like notation) as something the developer doesn't want to have optimized/obfuscated.

That's right.
 
There are indeed cases in which I need to append properties to GM objects, particularly when __gm_id doesn't cut it or when I need to create in the GM object an awareness of the soundings (the wrapper for instance), so

shape = new CustomShape( /* constructor provides a CustomShape.id*/ );
shape.poly = new google.maps.Polygon(...);
shape.poly['parentId'] = shape.id;

or something in this line. Of course the second and third lines happen within the constructor, but I'm lazy to fix that now.

Do you think using the __gm_id property has any serious disadvantages other than not having the guarantee that it'll the same the next time 'round, when I F5 the app?

The disadvantage is that __gm_id is undocumented: we may change or remove it in future, which may cause your page to spontaneously break.
 
Also, what's the deal with the messed up events? Why are some events simple objects with just lat/long, and others are more complex dom events, with a long property chain and stuff like event.responseValue, yadda yadda? Why aren't all events triggered in the map following the same pattern?

There are several types of event (listed in the v3 reference).  These include:
  • "Event"s are generated by the DOM and simply forwarded to the API object.  For example, marker event "click" is a DOM event.
  • "MouseEvent"s are synthesized from lower-level events.  For example, marker event "drag" is not fired by the browser but synthesized by the API for your benefit.
  • "KmlMouseEvent" and "FusionTablesMouseEvent" are specialized events which forward more information than just a MouseEvent.  For example, clicking on a feature in a KmlLayer or FusionTablesLayer fetches metadata for that feature which is then sent to your listener.
 
Should I move this question to a different (perhaps a new) post?

If your question about events relates to implementing wrapper objects, it's fine to continue in this thread.
 
Thank you!!!
Reply all
Reply to author
Forward
0 new messages