2016-11-15 2 views
1

Sie können das Verhalten einer Leaflet.js-Klasse durch including a mixin ändern.Verhalten einer Leaflet-Klasse über include() ändern

Das Tutorial Extending Leaflet: Class Theory sagt:

Wenn eine Klasse bereits definiert ist, bestehende Objekte/Methoden neu definiert werden können, oder neue können mit .include() hinzugefügt werden:

jedoch Beim Versuch, dies zu tun, erhalte ich einen Maximum call stack size exceeded Fehler.

var DemoClass = L.Class.extend({ 
 
    value: 42, 
 
    demoMethod: function() { 
 
    return this.value; 
 
    } 
 
}); 
 

 
DemoClass.include({ 
 
    demoMethod: function() { 
 
    return DemoClass.prototype.demoMethod.call(this) * 2; 
 
    }, 
 
    secondMethod: function() { 
 
    return this.value; 
 
    } 
 
}); 
 

 
var instance = new DemoClass(); 
 
console.log("value=" + instance.value); 
 
console.log("secondMethod()=" + instance.secondMethod()); 
 
console.log("demoMethod()=" + instance.demoMethod()); // gives a call stack exceeded
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>

Wenn es relevant ist, überschreibt der eigentliche Code L.Marker.onAdd().

Antwort

1

Versuchen Sie, die Basisfunktion zu isolieren:

var DemoClass = L.Class.extend({ 
 
    value: 42, 
 
    demoMethod: function() { 
 
    return this.value; 
 
    } 
 
}); 
 

 
DemoClass.include({ 
 
    baseDemoMethod: DemoClass.prototype.demoMethod, 
 
    demoMethod: function() { 
 
    return this.baseDemoMethod() * 2; 
 
    }, 
 
    secondMethod: function() { 
 
    return this.value; 
 
    } 
 
}); 
 

 
var instance = new DemoClass(); 
 
console.log("value=" + instance.value); 
 
console.log("secondMethod()=" + instance.secondMethod()); 
 
console.log("demoMethod()=" + instance.demoMethod());
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>

1
demoMethod: function() { 
    return DemoClass.prototype.demoMethod.call(this) * 2; 
    }, 

Sie machen einen unendlichen rekursiven Aufruf, genau dort.

JS ist manchmal seltsam, und dieses Mal ist einer von denen. Unter Bezugnahme auf DemoClass.prototype beziehen Sie sich auf die neueste ZustandDemoClass.prototype ... so DemoClass.prototype.demoMethod bezieht sich auf selbst.

Wenn Sie eine Prototypmethode oder -eigenschaft überschreiben, erhält die vorherige de-referenced and potentially garbage-collected.

Wenn Sie auf die vorherige Definition der Methode, , verweisen möchten, müssen Sie einen Verweis auf die vorherige Definition der Methode behalten.

Dies erfordert normalerweise einige Tricks in Form einer JS closure (behalten einen Verweis auf den ursprünglichen Wert in einigen kontrollierten Variablen Umfang). Es gibt eine Vielzahl von Möglichkeiten, dies zu tun: einen Verweis auf den vorherigen Prototyp als Klasseneigenschaft beizubehalten, wie es @Jaws tut; mach irgendwo eine Schließung; Machen Sie eine IIFE wie in Leaflet.GridLayer.FadeOut, oder irgendetwas, mit dem Sie einen Verweis auf die ursprüngliche Methodendefinition behalten können.

Verwandte Themen