Last active
November 12, 2017 20:42
-
-
Save johnspackman/f109bae1756e6f19f30c429c007f9c95 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Provides a registry of top level objects | |
*/ | |
qx.Class.define("qx.core.Id", { | |
extend: qx.core.Object, | |
include: [ qx.core.MObjectId ], | |
type: "singleton", | |
members: { | |
/* | |
* @Override | |
*/ | |
_createObjectImpl: function(id) { | |
switch(id) { | |
case "application": | |
return qx.core.Init.getApplication() || undefined; | |
} | |
return; // undefined | |
} | |
}, | |
statics: { | |
/** | |
* Returns a top level instance | |
* | |
* @param id {String} the ID to look for | |
* @return {qx.core.Object?} the object | |
*/ | |
getObject: function(id) { | |
return this.getInstance().getObject(id); | |
} | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* A mixin providing objects by ID and owners. | |
*/ | |
qx.Mixin.define("qx.core.MObjectId", | |
{ | |
/* | |
***************************************************************************** | |
PROPERTIES | |
***************************************************************************** | |
*/ | |
properties: { | |
/** The ID of the owning object */ | |
owner : { | |
check : "qx.core.Object", | |
init : null, | |
nullable : true, | |
apply : "_applyOwner" | |
}, | |
/** The ID of the object. Must be unique if no owner is specified */ | |
objectId : | |
{ | |
check : "String", | |
nullable : false, | |
apply : "_applyObjectId" | |
}, | |
}, | |
/* | |
***************************************************************************** | |
MEMBERS | |
***************************************************************************** | |
*/ | |
members: { | |
__ownedObjects: null, | |
/** | |
* apply owner id | |
*/ | |
_applyOwner : function(value, old) | |
{ | |
// todo: check if we have to move to new owner | |
// for example, if objectId has been assigned before ownerId | |
// apply to DOM node | |
if(value && value.getObjectId()) { | |
this.getContentElement().setAttribute("data-object-id", value.getObjectId()); | |
} | |
}, | |
/** | |
* apply object id | |
*/ | |
_applyObjectId : function(value, old) { | |
// for the moment, do not allow change since that needs to be handled | |
if (old ){ | |
this.error("Changing object ID not allowed"); | |
} | |
// apply to DOM node | |
if (value && value.getOwner()) { | |
this.getContentElement().setAttribute("data-object-id", value.getObjectId()); | |
} | |
}, | |
/** | |
* Returns the object with the specified ID | |
* | |
* @param id {String} ID of the object | |
* @return {qx.core.Object?} the found object | |
*/ | |
getObject: function(id) { | |
if (this.__ownedObjects) { | |
var obj = this.__ownedObjects[id]; | |
if (obj !== undefined) { | |
return obj; | |
} | |
} | |
// Handle paths | |
if (id.indexOf('/') > -1) { | |
var segs = id.split('/'); | |
var target = this; | |
var found = segs.every(seg => { | |
if (!seg.length) | |
return true; | |
if (!target) | |
return false; | |
var tmp = target.getObject(seg); | |
if (tmp !== undefined) { | |
target = tmp; | |
return true; | |
} | |
}); | |
return found ? target : undefined; | |
} | |
// No object, creating the object | |
var obj = this._createObjectImpl(id); | |
if (obj !== undefined) { | |
if (!this.__ownedObjects) { | |
this.__ownedObjects = {}; | |
} | |
obj.setOwner(this); | |
obj.setObjectId(id); | |
this.__ownedObjects[id] = obj; | |
} | |
return obj; | |
}, | |
/** | |
* Creates the object, intended to be overridden. Null is a valid return value and will be | |
* cached by `getObject`, however `undefined` is NOT a valid value and so will not be cached | |
* meaning that `_createObjectImpl` will be called multiple times until a valid value is returned. | |
* | |
* @param id {String} ID of the object | |
* @return {qx.core.Object?} the created object | |
*/ | |
_createObjectImpl: function(id) { | |
return; // Return undefined | |
}, | |
/** | |
* Discards an object from the list of owned objects; note that this does not dispose of the object, | |
* simply forgets it if it exists. | |
* | |
* @param id {String} the ID of the object to discard | |
*/ | |
discardObject: function(id) { | |
if (id.indexOf('/') > -1) | |
throw new Error("Cannot discard owned objects based on a path"); | |
if (this.__ownedObjects) { | |
var obj = this.__ownedObjects[id]; | |
if (obj) | |
obj.setOwner(null); | |
delete this.__ownedObjects[id]; | |
} | |
}, | |
/** | |
* Returns an array of objects that are owned by this object, or an | |
* empty array if none exists. | |
* | |
* @return {Array} | |
*/ | |
getOwnedObjects : function(){ | |
return this.__ownedObjects ? Object.values(this.__ownedObjects) : []; | |
} | |
} | |
}); |
Can you explain: say you call myObject.getObject("foo")
and it doesn't have this id in its list of owned objects. Why would it then call _createObjectImpl("foo")
? I assume this is to allow custom search paths?
No, it's so that objects are created on demand; _createObjectImpl("foo")
is guaranteed to be called only once for "foo"
and it's result is cached.
The only issue I've had with this pattern is where I have:
construct: function() {
this.base(argument);
this.add(this.getObject("lst"));
},
members: {
_createObjectImpl: function(id) {
switch(id) {
case "ctlr":
return new qx.data.controller.List(null, this.getObject("lst"), "title");
case "lst":
return new qx.ui.form.List();
What happens here is that the controller is never instantiated and so lst
appears on screen but empty. The solution is to add this.getObject("ctlr")
to the constructor, which is a little un-intuitive.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
ah yes 👍