有没有办法在jQuery UI中的窗口小部件的继承中具有多态性?
例如,我想做的事情如下:
$.widget('tr.fatherClass', {
getValue: function() {
return null;
}
...
});
// sonClass1: extends from the father
$.widget('tr.sonClass1', $.tr.fatherClass, {
getValue: function() {
return this._fooFunction1();
}
...
});
// sonClass2: extends from the father
$.widget('tr.sonClass2', $.tr.fatherClass, {
getValue: function() {
return this._fooFunction2();//
}
...
});
// create an instance of a "sonClass"
$('#foo1').sonClass1(options);
$('#foo2').sonClass2(options);
然后我想在不知道子类名称的情况下使用方法“getValue”:
$('#foo1').fatherClass('getValue'); // run _fooFunction1() of sonClass1
$('#foo2').fatherClass('getValue'); // run _fooFunction2() of sonClass2
但这不可能:
jquery.js:250 Uncaught Error: cannot call methods on variable prior to initialization; attempted to call method 'getValue'
在JQuery论坛上,Scott Gonzalez解释说“创建小部件只会创建一个小部件,而不是原型链中的每个小部件“ 链接
有一种解决方法或解决方案以优雅的方式做到这一点吗?
你可以保存 fatherClass
作为一个 data
对于具有某些键的元素 fatherObject
它应该在父亲的 _create()
方法...
$.widget('tr.fatherClass', {
_create: function(){
$(this.element).data( 'fatherObject', $.tr.fatherClass.prototype );
},
...
};
然后使用...检索值
$('#foo').data('fatherObject').getValue()
要么
$('#bar').data('fatherObject').getValue()
$.widget('tr.fatherClass', {
_create: function(){
$(this.element).data( 'fatherObject', $.tr.fatherClass.prototype );
},
getValue: function() {
return 'yellow'; // Father likes yellow
}
});
// extends from the father
$.widget('tr.sonClass', $.tr.fatherClass, {
getValue: function() {
return 'blue'; // Son likes blue
}
});
// extends from the father
$.widget('tr.daughterClass', $.tr.fatherClass, {
getValue: function() {
return 'pink'; // Daughter likes pink
}
});
// This is son
$('#foo').sonClass();
// This is daughter
$('#bar').daughterClass();
// Son's fav color
console.log( $('#foo').sonClass('getValue') );
// Son's FATHER's fav color
console.log( $('#bar').data('fatherObject').getValue() );
// Daughter's fav color
console.log( $('#bar').daughterClass('getValue') );
// Daughter's FATHER's fav color
console.log( $('#bar').data('fatherObject').getValue() );
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<div id='foo'></div>
<div id='bar'></div>
在OOD中,重要的是支持组合而不是继承。但是如果您仍然想要多态,而不是切换插件,您可以创建一个函数作为插件变量,您可以在应用程序逻辑中覆盖
例:
$.widget('myWidget', {
getValue: function() {
if(userfunc != null)
return userfunc();
return null;
}
userfunc: null
});
然后你可以为userfunc创建不同的版本
userfunc1 = function(){ return 43; }
userfunc2 = function(){ return 38; }
$('#foo').myWidget({userfunc : userfunc1})
value = $('#foo').myWidget('getValue') <= returns 47
$('#foo').myWidget({userfunc : userfunc2})
value = $('#foo').myWidget('getValue') <= returns 38
希望这可以帮助
无法从窗口小部件声明外部访问已写入的父方法,但是如果您已经编写过 sonClass
你自己,你可以通过使用从父亲调用相同的方法 this._super()
,在你的实施 sonClass
会看起来像这样......
// extends from the father
$.widget('tr.sonClass', $.tr.fatherClass, {
getValue: function( fromFather ) {
if ( 'father' == fromFather ) { // If 'father' is passed as argument
return this._super(); // Get the result from father's method
} else {
return this._$input.val();
}
}
...
});
你可以像这样从父亲那里打电话给...
console.log( $('#foo').sonClass('getValue', 'father') );
以供参考
http://api.jqueryui.com/jQuery.widget/#method-_super
UPDATE
我们添加新的 fathersMethod
返回父亲的父亲的方法...
$.widget('tr.fatherClass', {
//Add this to father to get properties from father
fathersMethod: function(prop) {
if ( typeof $.tr.fatherClass.prototype[prop] == 'function' )
return $.tr.fatherClass.prototype[prop]();
},
getValue: function() {
return 'yellow'; // Father likes yellow
},
...
...
...
});
现在对于任何继承父亲的儿子(或女儿)......可以像这样打电话给父亲的方法......
$('#foo').sonClass('fathersMethod', 'getValue');
这是一个更新的片段;-)
$.widget('tr.fatherClass', {
fathersMethod: function(prop) {
if ( typeof $.tr.fatherClass.prototype[prop] == 'function' )
return $.tr.fatherClass.prototype[prop]();
},
getValue: function() {
return 'yellow'; // Father likes yellow
}
});
// extends from the father
$.widget('tr.sonClass', $.tr.fatherClass, {
getValue: function() {
return 'blue'; // Son likes blue
}
});
// extends from the father
$.widget('tr.daughterClass', $.tr.fatherClass, {
getValue: function() {
return 'pink'; // Daughter likes pink
}
});
// This is son
$('#foo').sonClass();
// This is daughter
$('#bar').daughterClass();
// Son's fav color
console.log( $('#foo').sonClass('getValue') );
// Son's FATHER's fav color
console.log( $('#foo').sonClass('fathersMethod', 'getValue') );
// Daughter's fav color
console.log( $('#bar').daughterClass('getValue') );
// Daughter's FATHER's fav color
console.log( $('#bar').daughterClass('fathersMethod', 'getValue') );
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<div id='foo'></div>
<div id='bar'></div>
通常你在这里调用的多态是标准继承和实例化行为。
$('#foo1').sonClass1(options);
$('#foo2').sonClass2(options);
创建两个不同的类实例。
foo1.getValue
将在这里执行实例化的类 sonClass1, getValue
定义(代码块),它是fooFunction1。
foo2.getValue
将在这里执行实例化类 sonClass2, getValue
定义(代码块),它是fooFunction2。
后来打电话到这里
$('#foo1').fatherClass('getValue'); // run _fooFunction1() of sonClass1
$('#foo2').fatherClass('getValue'); // run _fooFunction2() of sonClass2
打电话不是 sonClass1 要么 sonClass2 getValue
方法的定义,但是 fatherClass。
在上述两种情况下,您通常都会期望父亲的情况 getValue
要使用的方法定义。
然而,您的错误表明它未定义。
我不使用JQuery但我怀疑它的继承机制没有实例化父类。
我们所有使用过js的人都遇到过这个问题,并以各种方式解决了这个问题。