我的图表应用程序中有许多逻辑对象,每个逻辑对象都包含许多Raphael对象。例如,数据点可能包含圆圈和标题。
我希望能够将所有这些对象作为一个对象进行处理,并且还能够确定任何给定的Raphael元素属于哪个逻辑对象(例如,处理鼠标单击逻辑元素的上下文中的元素)它属于。。
我希望能够创建Raphael.st的子类(即Raphael集),并覆盖push方法以将element.data(" object")设置为包含逻辑对象。
在代码的其他地方,我使用以下子类方法(我在Stack Overflow上找到):
/**
* Utility function to help subclassing
* @param base
* @param sub
*/
function subclass(base, sub) {
// Avoid instantiating the base class just to setup inheritance
// See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create
// for a polyfill
sub.prototype = Object.create(base.prototype);
// Remember the constructor property was set wrong, let's fix it
sub.prototype.constructor = sub;
// In ECMAScript5+ (all modern browsers), you can make the constructor property
// non-enumerable if you define it like this instead
Object.defineProperty(sub.prototype, 'constructor', {
enumerable: false,
value: sub
});
}
但是,此方法抛出异常,因为base = Raphael.st时base.prototype为null。
我为无知子类如何在javascript中真正起作用而道歉 - 我意识到盲目地从其他地方复制代码并不理想,但我还没有找到我理解的解释!
任何人都可以告诉我如何将Raphael.st分类,和/或指出我的解释方向,这将使我能够找到适合自己的方法吗?
答案 0 :(得分:1)
将Raphael.set子类化并不是一个好主意,因为Raphael并不期待它。例如,Raphael中需要知道它是否处理集合的大量代码使用如下代码:
if (element.constructor == R.st.constructor)
这意味着一个合适的子类将无法通过测试。
如果您仍想继续(并且没有任何冲突属性或功能名称,就像我在尝试时所做的那样!),我确实找到了答案。
需要修改子类函数,因为Raphael不遵循通常的惯例 - Raphael.st不是类,它是类的原型。因此,子类方法应修改如下:
function subclass(base, sub) {
// Avoid instantiating the base class just to setup inheritance
// See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create
// for a polyfill
sub.prototype = Object.create(base.prototype ? base.prototype : base);
// Remember the constructor property was set wrong, let's fix it
sub.prototype.constructor = sub;
// In ECMAScript5+ (all modern browsers), you can make the constructor property
// non-enumerable if you define it like this instead
Object.defineProperty(sub.prototype, 'constructor', {
enumerable: false,
value: sub
});
}
这是子类构造函数:
/**
* @param paper Raphael Paper
*/
var MySet = function(paper) {
Raphael.st.constructor.call(this);
// Without this, Raphael does not recognise MySet objects as sets
// because it tests constructor value using == instead of instanceof
this.constructor = Raphael.st.constructor;
// Cheat!! Copied this code from Raphael Paper.set()
this.paper = paper;
};
subclass(Raphael.st, MySet);
希望这有助于其他人!