admin管理员组文章数量:1355638
Is there a way to have polymorphism in the inheritance of a widget in jQuery UI?
For example I want to do something like:
$.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);
Then I want to use the method "getValue" without knowing the name of the son class:
$('#foo1').fatherClass('getValue'); // run _fooFunction1() of sonClass1
$('#foo2').fatherClass('getValue'); // run _fooFunction2() of sonClass2
But this is not possible:
jquery.js:250 Uncaught Error: cannot call methods on variable prior to initialization; attempted to call method 'getValue'
In the forum of JQuery, Scott Gonzalez explains that "Creating a widget only creates one widget, not every widget in the prototype chain" link
There is any workaround or solution to do this in an elegant way?
Is there a way to have polymorphism in the inheritance of a widget in jQuery UI?
For example I want to do something like:
$.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);
Then I want to use the method "getValue" without knowing the name of the son class:
$('#foo1').fatherClass('getValue'); // run _fooFunction1() of sonClass1
$('#foo2').fatherClass('getValue'); // run _fooFunction2() of sonClass2
But this is not possible:
jquery.js:250 Uncaught Error: cannot call methods on variable prior to initialization; attempted to call method 'getValue'
In the forum of JQuery, Scott Gonzalez explains that "Creating a widget only creates one widget, not every widget in the prototype chain" link
There is any workaround or solution to do this in an elegant way?
Share Improve this question edited Jul 10, 2016 at 15:20 Troncador asked Jun 30, 2016 at 14:18 TroncadorTroncador 3,5763 gold badges25 silver badges41 bronze badges 2- This is not how jQuery plugins work. You have to handle your logic in same plugin. What real world advantage do you gain from this? – T J Commented Jul 4, 2016 at 6:21
- I can create an interface and control different kinds of widget with the same interface – Troncador Commented Jul 5, 2016 at 6:35
4 Answers
Reset to default 3In OOD is important to favor position over inheritance. But if you still want polymorphism, instead of switching plugins you can create a function as a plugin variable you can overwrite in your application logic
Example:
$.widget('myWidget', {
getValue: function() {
if(userfunc != null)
return userfunc();
return null;
}
userfunc: null
});
and then you can create different versions for 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
Hope this helps
You can save fatherClass
as a data
for element with some key like fatherObject
it should go in father's _create()
method...
$.widget('tr.fatherClass', {
_create: function(){
$(this.element).data( 'fatherObject', $.tr.fatherClass.prototype );
},
...
};
And later retrieve values using...
$('#foo').data('fatherObject').getValue()
or
$('#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./jquery-1.10.2.js"></script>
<script src="//code.jquery./ui/1.11.4/jquery-ui.js"></script>
<div id='foo'></div>
<div id='bar'></div>
There is no way to access over written parent's methods from outside the widget declaration, but if you have written sonClass
yourself, you can call same method from parent by using this._super()
, implementation in your sonClass
will look something like this...
// 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();
}
}
...
});
You can call method from father like this...
console.log( $('#foo').sonClass('getValue', 'father') );
For reference
http://api.jqueryui./jQuery.widget/#method-_super
UPDATE
We add new fathersMethod
method to father which returns results from father...
$.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
},
...
...
...
});
Now for any son (or daughter) who inherits from father... can call father's methods like this...
$('#foo').sonClass('fathersMethod', 'getValue');
Here's an updated snippet ;-)
$.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./jquery-1.10.2.js"></script>
<script src="//code.jquery./ui/1.11.4/jquery-ui.js"></script>
<div id='foo'></div>
<div id='bar'></div>
Normally what you're calling here polymorphism is standard inheritance and instantiation behaviour.
$('#foo1').sonClass1(options);
$('#foo2').sonClass2(options);
creates two distinct class instances.
foo1.getValue
will execute the instantiated classes, here sonClass1, getValue
defintion (code block) which is fooFunction1.
foo2.getValue
will execute the instantiatedclass's, here sonClass2, getValue
definition (code block) which is fooFunction2.
The later calls here
$('#foo1').fatherClass('getValue'); // run _fooFunction1() of sonClass1
$('#foo2').fatherClass('getValue'); // run _fooFunction2() of sonClass2
are calls not to the sonClass1 or sonClass2 getValue
method defintions but that of the fatherClass.
You would normally expect in both the above cases for the father's getValue
method defintion to be used.
Your error however says it's undefined.
I don't use JQuery but I would suspect it's inheritance mechanism does not instantiate the parent class.
All of us who have been using js have encountered this issue and have resolved it in a variety of ways.
本文标签: javascriptJQuery UI inheritance polymorphismStack Overflow
版权声明:本文标题:javascript - JQuery UI inheritance polymorphism - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1743982491a2571140.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论