Reputation: 4280
I would like to extend/derive from the XML Document returned by jQuery's $.parseXML()
function, to add my own properties/functions. I am new to jQuery/JavaScript object inheritance. I have tried to read all over the web but am not "getting" it.
In, say, C# classes I could write something (kept simple) like this:
public class MyXmlDocument : XmlDocument
{
public MyXmlDocument(string xmlText)
{
this.LoadXml(xmlText);
}
public string SomeVariable;
...
public XmlNode FindCertainNode()
{
return this.SelectSingleNode("certain");
}
...
}
MyXmlDocument xmlDoc = new MyXmlDocument(xmlText);
xmlDoc.AppendChild(...); // XmlDocument method
XmlNode xmlNode = xmlDoc.FindCertainNode(); // MyXmlDocument method
etc.
I hesitate to show my jQuery/JavaScript attempt because I am quite at sea, but I know people like to see something, so please regard it as "some ideas I have been playing with":
// One approach
function XMLDoc(xmlText)
{
var parseXML = function (xmlText)
{
//var parser = new DOMParser();
//var xmlDoc = parser.parseFromString(xmlText, "text/xml");
var xmlDoc = $.parseXML(xmlText);
return xmlDoc;
};
var findCertainNode = function ()
{
return this.find('certain');
}
return parseXML(xmlText);
}
// Another approach
var XMLDoc = $.extend({}, $.parseXML.prototype, {
findCertainNode: function () {
this.find('certain');
}
});
I am expecting to be able to access existing functionality for the XML document plus my own extensions, along the lines of:
var xmlDoc = new XMLDoc(xmlText);
var $xmlDoc = $(xmlDoc);
$xmlDoc.find('certain'); // jQuery method
$xmlDoc.findCertainNode(); // my additional method
I also know that I am unclear about whether my code should be returning plain JavaScript objects or jQuery ones. I am thinking jQuery ones, so that I can easily call for example jQuery's .find()
etc.
It is important to me that the code should all be wrapped inside a single function/object or similar for editing/viewing, as both my attempts do.
If someone could show how they would implement the C# pattern I think that would answer my question, and I should be most grateful.
EDIT: Solution
I am marking @Karol's solution below (https://stackoverflow.com/a/42672481/489865) as the accepted one as he did the most work to answer my question as phrased.
However, I have come to realise that the object returned from $.parseXML()
/DOMParser().parseFromString()
is not some special "XML document", it's just an element, and as such has no special methods. It is not worth it to derive/inherit from it, and so encapsulation is adequate and simpler. My pattern looks like:
var XMLDoc = function (xmlText) {
this._xmlDoc = $.parseXML(xmlText);
};
$.extend(XMLDoc.prototype, {
doc: this._xmlDoc,
find: function (selector) {
return $(this._xmlDoc).find(selector);
},
findCertain: function () {
return $(this._xmlDoc).find("certain");
},
...
});
var xmlDoc = new XMLDoc(xmlText);
xmlDoc.find('something');
xmlDoc.findCertainNode();
Upvotes: 1
Views: 259
Reputation: 4774
Try to do sth like this:
function XMLDoc(xmlText) { //constructor
this._xmlDoc = $.parseXML(xmlText); //'_' is JS convention for private fields
}
XMLDoc.prototype = {
findCertainNode: function() {
return $(this._xmlDoc).find('certain');
}
/* other methods here */
}
var myXML = new XMLDoc('<a><certain /></a>')
myXML.findCertainNode(); //[<certain />]
Or the same with ES6 syntax:
class XMLDoc {
constructor(xmlText) {
this._xmlDoc = $.parseXML(xmlText);
}
findCertainNode() {
return $(this._xmlDoc).find('certain');
}
}
var myXML = new XMLDoc('<a><certain /></a>')
myXML.findCertainNode(); //[<certain />]
I think the real inheritance from jQuery is impossible, but if you really want to have an ability to use it in C# way, you can do sth like this:
Object.keys(Object.getPrototypeOf($())).forEach(function(key){
XMLDoc.prototype[key] = function() {
return $(this._xmlDoc)[key].apply(null, arguments);
}
})
Or in ES6:
Object.keys(Object.getPrototypeOf($())).forEach(key => {
XMLDoc.prototype[key] = () => {
return $(this._xmlDoc)[key](...arguments);
}
})
Then you can fire all jQuery methods as they were inherited.
And if you'd like to overload some of them, remember to do this overloading after the code above.
Upvotes: 1
Reputation: 2301
Try with:
var xmlDoc = new XMLDoc(xmlText);
$.extend( xmlDoc, {
find: function(par){
// your function
}
});
Upvotes: 1