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

RICHARD Didier didier.richard at ign.fr
Mon Jul 25 16:05:18 EDT 2011


> 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



More information about the Dev mailing list