implement hooks for Class constructors (AOP-style), close #1123

This commit is contained in:
Vladimir Agafonkin 2012-12-12 12:26:33 +02:00
parent 8350bb1e08
commit 782e8e7dcf
3 changed files with 81 additions and 38 deletions

View File

@ -106,6 +106,38 @@ describe("Class", function() {
foo3: 4
});
});
it("should add constructor hooks correctly", function () {
var spy1 = jasmine.createSpy("init hook 1");
Klass.addInitHook(spy1);
Klass.addInitHook('bar', 1, 2, 3);
var a = new Klass();
expect(spy1).toHaveBeenCalled();
expect(method).toHaveBeenCalledWith(1, 2, 3);
});
it("should inherit constructor hooks", function () {
var spy1 = jasmine.createSpy("init hook 1"),
spy2 = jasmine.createSpy("init hook 2");
Klass.addInitHook(spy1);
var Klass2 = Klass.extend({});
Klass2.addInitHook(spy2);
var a = new Klass();
expect(spy1).toHaveBeenCalled();
expect(spy2).not.toHaveBeenCalled();
var b = new Klass2();
expect(spy2).toHaveBeenCalled();
expect(spy1.argsForCall.length).toBe(2);
});
});
// TODO Class.include

View File

@ -8,9 +8,16 @@ L.Class.extend = function (/*Object*/ props) /*-> Class*/ {
// extended class with the new prototype
var NewClass = function () {
// call the constructor
if (this.initialize) {
this.initialize.apply(this, arguments);
}
// call all constructor hooks
for (var i = 0, len = this._initHooks.length; i < len; i++) {
this._initHooks[i].call(this);
}
};
// instantiate class without calling constructor
@ -49,6 +56,9 @@ L.Class.extend = function (/*Object*/ props) /*-> Class*/ {
// mix given properties into the prototype
L.extend(proto, props);
// inherit constructor hooks
proto._initHooks = this.prototype._initHooks ? this.prototype._initHooks.slice() : [];
return NewClass;
};
@ -58,6 +68,18 @@ L.Class.include = function (props) {
L.extend(this.prototype, props);
};
// merge new default options to the Class
L.Class.mergeOptions = function (options) {
L.extend(this.prototype.options, options);
};
// add a constructor hook
L.Class.addInitHook = function (fn) { // (Function) || (String, args...)
var args = Array.prototype.slice.call(arguments, 1);
var init = typeof fn === 'function' ? fn : function () {
this[fn].apply(this, args);
};
this.prototype._initHooks.push(init);
};

View File

@ -25,7 +25,6 @@ L.Map = L.Class.extend({
this._initContainer(id);
this._initLayout();
this._initHooks();
this._initEvents();
if (options.maxBounds) {
@ -681,16 +680,6 @@ L.Map = L.Class.extend({
}
});
L.Map.addInitHook = function (fn) {
var args = Array.prototype.slice.call(arguments, 1);
var init = typeof fn === 'function' ? fn : function () {
this[fn].apply(this, args);
};
this.prototype._initializers.push(init);
};
L.map = function (id, options) {
return new L.Map(id, options);
};