问题
Would like to make a custom control for my DataObjects which would have two properties, the javaClass and the javaModel.
So if I have a java class names acme.com.model.Person, the javaClass property would be acme.com.model.Person and the javaModel property would be Person.
I started to build my custom control but only got a few things put in before I ran into syntactical problems.
The real problem is createObject. I don't understand how I can replace the presently hard-coded "Person" in the createObject with my compositeData values. Is this even possible?
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core"
xmlns:xe="http://www.ibm.com/xsp/coreex">
<xp:this.data>
<xe:objectData
saveObject="#{javascript:compositeData.javaModel + 'save()'}"
var="${javascript:compositeData.javaModel}">
<xe:this.createObject><![CDATA[#{javascript:var Person = new com.scoular.model.Person();
var unid = context.getUrlParameter("key")
if (unid != "") {
Person.loadByUnid(unid);
viewScope.put("readOnly","Yes");
} else {
Person.create();
viewScope.put("readOnly","No");
}
return Person;}]]></xe:this.createObject>
</xe:objectData>
</xp:this.data>
</xp:view>
回答1:
Just as you might try to de-couple your business logic from your "UI" (XPages markup), you could move your "create" code to a constructor method to the Person
class, one which:
- calls out to check for the URL Parameter of "key"
- sets the key to a property (making this a bit more bean-like, optional, but likely a good idea)
- invokes the
loadByUnid(String)
method - and puts the appropriate
readOnly
value intoviewScope
public class Person implements Serializable {
private static final long serialVersionUID = 1L;
// constructor method
public Person(){
Map<String, Object> reqParm = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
String unid = (String) reqParm.get("key");
Map<String, Object> vwScope = ExtLibUtil.getViewScope();
if (unid != "") {
this.loadByUnid(unid);
vwScope.put("readOnly","Yes");
} else {
this.create();
viewScope.put("readOnly","No");
}
}
//...
}
Then your createObject
block would look more like:
<xe:this.createObject><![CDATA[#{javascript:return new com.scoular.model.Person();}]]></xe:this.createObject>
This should shift enough of the specifics off of the markup layer so as to be far more reusable across specific classes, provided each self-construct like that.
As for the general mixing compositeData
with text, you should be passing an object reference so for the example of the save method above, I think you should be able to access it more via compositeData.javaModel.save();
, provided the save
method exists in the object referenced by compositeData.javaModel
. I don't think appending the string of a method will work, but I can't say I've tried it that way.
来源:https://stackoverflow.com/questions/41709010/xpages-objectdata-custom-control-mixing-compositedata-with-text