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

Andreas Hocevar ahocevar at opengeo.org
Mon Jul 25 17:39:50 EDT 2011


Hi Didier,

So what you implemented with your overload method results in the same as if you'd simply use OpenLayers.Class:

A = A.overload(A, {
    initialize:function() {
        this.p_= "A.initialize-new";
        OpenLayers.Console.info(this.p_); 
    },
    pa:"PA-new"
});

is equivalent to

A = OpenLayers.Class(A, {
    initialize:function() {
        this.p_= "A.initialize-new";
        OpenLayers.Console.info(this.p_); 
    },
    pa:"PA-new"
});

The problem here is that A becomes a subclass of itself. So what you could try instead to avoid this is

A = OpenLayers.Class(OpenLayers.Util.applyIf({
    initialize:function() {
        this.p_= "A.initialize-new";
        OpenLayers.Console.info(this.p_); 
    },
    pa:"PA-new"
}, A));

But either way, I wonder why you do this in the first place, instead of creating subclasses with your modifications.

Andreas.

On Jul 25, 2011, at 22:05 , RICHARD Didier wrote:

> 
>> Hi Didier,
>> 
> 
> Hi Andreas,
> 
>> what I showed you in the last snippet is exactly what happens in
>> OpenLayers.Class. So to do it the way we recommend, and if you're into
>> anonymous functions, you could do something like the following, which is
>> 100% OpenLayers API compliant:
>> 
>> var X = OpenLayers.Class({
>>    initialize: function() {
>>        this._p = "A.initialize";
>>        OpenLayers.Console.info(this._p);
>>    },
>>    ma: function() {
>>        OpenLayers.Console.info(this._p);
>>    }
>> });
>> var x1 = new (OpenLayers.Class(X, {
>>    initialize: function() {
>>        this._p = "A.initialize-new";
>>        OpenLayers.Console.info(this.p_);
>>    }
>> }));
>> 
> 
> I have tested something like this for my use case :
> 
> A= OpenLayers.Class({...});
> A.B= OpenLayers.Class(A, {...});
> 
> A= OpenLayers.Class(A, { ...});
> var a= new A(); //ok
> var ab= new AB(); //ko: A.B is not a constructor ...
> 
> My idea was just to overwrite part of a class path and have it propagated ...
> 
> I have this working in OL 2.10 (based on your snippet):
> 
> 
> 
>    /**
>     * Function: OpenLayers.overload
>     * Apply the patch to the given class and propagate it downward
>     * to the sub-classes by insuring that only not overwritten
>     * methods() or properties are overloaded.
>     *
>     * Parameters:
>     * P - {Object} an instance of {<OpenLayers.Class>}
>     * F - {Object} an object used to overwrite methods (including
>     * constructor) and properties of P and its sub-classes.
>     *
>     * Returns:
>     * {Object} the overloaded instance of given class.
>     */
>    OpenLayers.overload= function(P,F) {
>        //save old class
>        var X= P;
>        var xProto= OpenLayers.Util.extend({},P.prototype);
>        var f= OpenLayers.Util.extend({},F);
> 
>        if (typeof(F.initialize)=="function") {
>            // protect initializer from sub-classes overloading :
>            var pProto= P.prototype;
>            pProto.initialize= function() {
> F.initialize.apply(this,arguments); };
>            delete f["initialize"];
>            OpenLayers.Util.extend(pProto,f);
>            P= pProto.initialize;
>            P.prototype= pProto;
>        } else {
>            OpenLayers.Util.extend(P.prototype, f);
>        }
> 
>        // restore sub-classes:
>        // propagate constructor/properties/method to sub-class ...
>        for (var xn in X) {
>            var p= X[xn];
>            delete X[xn];
>            if (typeof(p)=='function' && p.prototype.initialize) {//ensure
> it is a Class
>                f= OpenLayers.Util.extend({},F);
>                // check for overloaded properties :
>                for (var fn in F) {
>                    var fp= F[fn];
>                    if (typeof(fp)=="function") {
>                        if (p.prototype[fn]===xProto[fn]) {
>                            // override method ...
>                            continue;
>                        }
>                        delete f[fn];
>                        continue;
>                    }
>                    if (p.prototype.hasOwnProperty(fn) &&
> X.prototype.hasOwnProperty(fn) && fp!==undefined) {
>                        if (p.prototype[fn]===xProto[fn]) {
>                            // override property ...
>                            continue;
>                        }
>                        delete f[fn];
>                        continue;
>                    }
>                }
>                // override sub-class :
>                var x= p;
>                var c= OpenLayers.Class(P,p.prototype);
>                OpenLayers.Util.extend(c,x);
>                P[xn]= OpenLayers.overload(c,f);
>            } else {
>                P[xn]= p;
>            }
>        }
>        xProto= null;
>        X= null;
> 
>        return P;
>    };
> 
> 
> 
> The classes tree is the one I sent yesterday:
> 
> 
>    A= OpenLayers.Class({
>        initialize:function() { this.p_= "A.initialize";
> OpenLayers.Console.info(this.p_); },
>        pa:"PA",
>        p_:null,
>        ma:function() { OpenLayers.Console.info("A.ma="+this.pa); }
>    });
>    A.B= OpenLayers.Class(A,{
>        pa:"PA-bis",
>        pb:"PB",
>        mb:function() { OpenLayers.Console.info("B.mb="+this.pa+"
> "+this.pb); }
>    });
>    A.B.D= OpenLayers.Class(A.B,{
>        initialize:function() { this.p_= "D.initialize";
> OpenLayers.Console.info(this.p_); }
>    });
>    A.B.E= OpenLayers.Class(A.B,{
>        initialize:function() { this.p_= "E.initialize";
> OpenLayers.Console.info(this.p_); }
>    });
>    A.C= OpenLayers.Class(A,{
>        initialize:function() { this.p_= "C.initialize";
> OpenLayers.Console.info(this.p_); },
>        pc:"PC",
>        ma:function() { OpenLayers.Console.info("C.ma="+this.pa+"
> "+this.pc); }
>    });
>    A.C.F= OpenLayers.Class(A.C,{
>        pf:"PF",
>        mf:function() { OpenLayers.Console.info("F.mf="+this.pa+"
> "+this.pc+" "+this.pf); }
>    });
>    A.C.G= OpenLayers.Class(A.C,{
>        pg:"PG",
>        ma:function() { OpenLayers.Console.info("G.ma="+this.pa+"
> "+this.pc+" "+this.pg); }
>    });
> 
> 
> 
> 
> and then :
> 
>    A= OpenLayers.overload(A, {
>        initialize:function() { this.p_= "A.initialize-new";
> OpenLayers.Console.info(this.p_); },
>        pa:"PA-new"
>    });
> 
> to overload the classes tree ...
> 
> The same method "almost works" in OL 2.11 except that in the end, I have
> got all sub-classes in the root, and so on recursively :
> 
> A
>  B
>    B
>    C
>    D
>    E
>  C
>    F
>      F
>      G
>    G
>  D
>  E
> 
> (again, in OL 2.10, everything looks good in the end)
> 
> I may be in the wrong path to solve my problem ...
> 
> Any thoughts ?
> 
>> Andreas.
> 
> 
> didier
> 
> _______________________________________________
> Dev mailing list
> Dev at lists.osgeo.org
> http://lists.osgeo.org/mailman/listinfo/openlayers-dev

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



More information about the Dev mailing list