开发者

CoffeeScript with other libraries

I recently started reading about CoffeeScript http://jashkenas.github.com/coffee-script/ and it looks absolutely amazing! However I can't seem to figure out if there's an easy way to access/use external JavaScript apis. I use OpenLayers extensively so could someone show me how the following snippet would be written in CoffeeScript?

var map = new OpenLayers.Map('map_div', {
    controls: [
        new OpenLayers.Control.PanZoomBar(),
        new OpenLayers.Control.LayerS开发者_如何转开发witcher({'ascending':false})
    ],
    numZoomLevels: 6    
});


One slight gotcha to be aware of is that the object system in OpenLayers uses a function called initialize() as the constructor, so in order to have CoffeeScript's super keyword work correctly when you extend OpenLayers classes, you'll need to decorate them. I use the following function for this:

window.CompatibleClass = (cls) ->
  class Wrapped
    constructor: ->
      # Call the OpenLayers-style constructor.
      cls::initialize.apply @, arguments

  # Copy prototype elements from OpenLayers class.
  Wrapped::[name] = el for name, el of cls::

  Wrapped

Now you can extend an OL built-in like so:

class MySpecialFeature extends (CompatibleClass OpenLayers.Feature.Vector)
  constructor: ->
    super new OpenLayers.Geometry.Point 0, 0

  CLASS_NAME: "MySpecialFeature"

EDIT: Just to clarify, the two alternatives to wrapping the class like this are to use the OpenLayers class system as-is, and miss out on some of the syntax benefits of CoffeeScript, or to manually call the initialize function in each constructor, which feels more brittle, and spreads around the dependency, rather than concentrating it in a single decorator.

Using the OpenLayers class system as-is, in CoffeeScript:

MySpecialFeature = OpenLayers.Class OpenLayers.Feature.Vector,
    initialize: ->
        # Call super using apply, as is convention in OpenLayers
        OpenLayers.Feature::initialize.apply @, new OpenLayers.Geometry.Point 0, 0
        ...
    ...

Alternatively, using CoffeeScript classes, but extending an OpenLayers class un-decorated:

class MySpecialFeature extends OpenLayers.Feature.Vector
    constructor: ->
        # Call inherited initialize().
        @initialize.apply @, new OpenLayers.Geometry.Point 0, 0
        ...
    ...

Neither of these methods will be as idiomatic or recognizable to other developers, either of OpenLayers or CoffeeScript. I stand by my recommendation of a wrapper which allows native super() use in calling OpenLayers constructors.


You have a bit of flexibility in how much syntax you use, but this is how I'd write it:

map = new OpenLayers.Map 'map_div',
    controls: [
        new OpenLayers.Control.PanZoomBar(),
        new OpenLayers.Control.LayerSwitcher ascending: false
    ]
    numZoomLevels: 6

This compiles into

var map;
map = new OpenLayers.Map('map_div', {
  controls: [
    new OpenLayers.Control.PanZoomBar(), new OpenLayers.Control.LayerSwitcher({
      ascending: false
    })
  ],
  numZoomLevels: 6
});

which is essentially the same as your JavaScript code.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜