[OpenLayers-Dev] 2.10 and 2.11-RC1 OpenLayers.Class behavior changes

Andreas Hocevar ahocevar at opengeo.org
Tue Jul 26 04:57:23 EDT 2011


Hi Didier,

see replies inline.

On Jul 26, 2011, at 09:41 , Richard Didier wrote:

>> The problem here is that A becomes a subclass of itself. So what you could
>> try instead to avoid this is
> 
> That's the reason why I have written OpenLayers.overload to avoid this problem. In OL 2.10, it is ok (the classes 
> tree remains perfect). In OL 2.11, the classes tree is broken ... I would like to understand why this method works 
> in OL 2.10 and not in OL 2.11 !(

The reason is that we now use JavaScript functions and prototypes the way they are supposed to be. Let's assume you want do create a class from the object Aproto:

var Aproto = {
    initialize: function() {
        this.enabled = false;
    },
    enable: function() {
        this.enabled = true;
    }
};

What OpenLayers.Class does is now basically just:

A = Aproto.initialize;
A.prototype = Aproto;

Now let's assume you want to create a subclass of A, from the object Bproto:

Bproto = {
    enable: function() {
        alert("I'm enabled now");
        A.prototype.enable.apply(this, arguments);
    }
};

To maintain the inheritance chain, OpenLayers.Class does something like this:

var B = function() {};
B.prototype = new A;
OpenLayers.Util.extend(B.prototype, Bproto);

Now what you could do to overload the constructor of B is the following:

var BTemp = function() { /* the initialize function */ }
BTemp.prototype = B.prototype;
B = BTemp;

This should give you the desired result. For all other methods/properties, you can do the same as you did in 2.10.

But again, I'd recommend against doing all this in the first place. See my other replies below for an alternative.

> 
>> A = OpenLayers.Class(OpenLayers.Util.applyIf({
>>    initialize:function() {
>>        this.p_= "A.initialize-new";
>>        OpenLayers.Console.info(this.p_);
>>    },
>>    pa:"PA-new"
>> }, A));
>> 
> 
> I guess OpenLayers.Util.applyIf is to be written based on extend/applyDefaults ?

I was half way between OpenLayers and Ext JS when I wrote this. I meant OpenLayers.Util.applyDefaults.

But it won't help you either, because it will interfer with the inheritance chain as well.

> 
>> But either way, I wonder why you do this in the first place, instead of
>> creating subclasses with your modifications.
>> 
> 
> The rational is many fold :
> 
> 1/ There are tickets for the next OL release that we incorporate directly in our production scripts. Usually, we try 
> to push fixes every three months and a new release a month or two after a new OL release;

You should apply these to the previous OpenLayers release.

> 2/ We insert patches directly in the OL classes tree (for instance, our GeoDRM mechanism or bugs reported by 
> users) and allow users to still use OL's API but patched !

Instead, you should create subclasses for these. They could live in a separate namespace as well. If these patches are relevant for a broader audience, you could also consider contributing them to the OpenLayers project.

> 3/ The OL library is split into several functional "ready to use" libraries like : hooks to our JS library allowing 
> developpers to use whatever OL they want or GeoExt or ... Another example is to forge a library without vector 
> stuffs in, another to have mobile things, another to have a small OL wrapper to talk with Flash, and so on ... For 
> doing that, we apply patches/overlay depending on the functionnality we aim at.

For this, you can use the OpenLayers build tool, or any other build tool that allows you to create a build from only the files you specify. Again, these files can come from different source trees and namespaces.

> The key issue is not to change OL API (Classes), possibly add new methods to OL API. For functionnalities not in 
> OL (mainly controlers), we have our own namespace.

Good, so let's say you want to add functionality to the WMS layer, but don't want to contribute it to OpenLayers. The appropriate way to do this would be:

IGN.Layer.WMS = OpenLayers.Class(OpenLayers.Layer.WMS, {
    initialize: function() { ... },
    customMethod: function() { ... }
});

In your application, you would create an instance of this custom WMS layer:

var myLayer = new IGN.Layer.WMS("ign", "http://ign.fr/wms", {layers: "ign"});

People can use this like any OpenLayers.Layer.WMS instance, plus use your customizations, e.g.

myLayer instanceof OpenLayers.Layer.WMS; // asserts true
myLayer.customMethod(); // customization
myLayer.setOpacity(.5); // OpenLayers.Layer.WMS method

Andreas.

-- 
Andreas Hocevar
OpenGeo - http://opengeo.org/
Expert service straight from the developers.



More information about the Dev mailing list