JQuery UI 继承多态
JQuery UI inheritance polymorphism
在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"不知道儿子的名字class:
$('#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 解释说“创建一个小部件只会创建一个小部件,而不是原型链中的每个小部件”link
有任何解决方法或解决方案可以优雅地完成此操作吗?
在 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
更新
我们向父亲添加新的 fathersMethod
方法,该方法 returns 来自父亲...
$.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);
创建两个不同的 class 实例。
foo1.getValue
将执行实例化的 classes,这里 sonClass1,getValue
定义(代码块)是 fooFunction1.
foo2.getValue
将执行实例化的class,这里是 sonClass2,getValue
定义(代码块)是 fooFunction2。
以后来电这里
$('#foo1').fatherClass('getValue'); // run _fooFunction1() of sonClass1
$('#foo2').fatherClass('getValue'); // run _fooFunction2() of sonClass2
不是调用 sonClass1 或 sonClass2 getValue
方法定义,而是调用 fatherClass .
您通常希望在上述两种情况下使用父亲的 getValue
方法定义。
然而你的错误说它是未定义的。
我不使用 JQuery 但我怀疑它的继承机制不会实例化父 class。
我们用过js的都遇到过这个问题,也通过各种方式解决了。
您可以将 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>
在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"不知道儿子的名字class:
$('#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 解释说“创建一个小部件只会创建一个小部件,而不是原型链中的每个小部件”link
有任何解决方法或解决方案可以优雅地完成此操作吗?
在 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
更新
我们向父亲添加新的 fathersMethod
方法,该方法 returns 来自父亲...
$.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);
创建两个不同的 class 实例。
foo1.getValue
将执行实例化的 classes,这里 sonClass1,getValue
定义(代码块)是 fooFunction1.
foo2.getValue
将执行实例化的class,这里是 sonClass2,getValue
定义(代码块)是 fooFunction2。
以后来电这里
$('#foo1').fatherClass('getValue'); // run _fooFunction1() of sonClass1
$('#foo2').fatherClass('getValue'); // run _fooFunction2() of sonClass2
不是调用 sonClass1 或 sonClass2 getValue
方法定义,而是调用 fatherClass .
您通常希望在上述两种情况下使用父亲的 getValue
方法定义。
然而你的错误说它是未定义的。
我不使用 JQuery 但我怀疑它的继承机制不会实例化父 class。
我们用过js的都遇到过这个问题,也通过各种方式解决了。
您可以将 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>