Xpages 将自定义控件中的编辑框动态绑定到托管bean
我已经阅读了许多关于自定义控件中动态绑定字段的优秀文章,但它们都假设了文档数据源 我想允许托管bean数据源的可能性。我尝试将属性类型设置为Xpages 将自定义控件中的编辑框动态绑定到托管bean,xpages,managed-bean,editbox,Xpages,Managed Bean,Editbox,我已经阅读了许多关于自定义控件中动态绑定字段的优秀文章,但它们都假设了文档数据源 我想允许托管bean数据源的可能性。我尝试将属性类型设置为com.ibm.xsp.model.DataSource或com.ibm.xsp.extlib.model.ObjectDataSource,但这两种类型均不适用于以下xml: <xp:inputText id="input" value="${compositeData.dsn[compositeData.fieldName]}" &
com.ibm.xsp.model.DataSource
或com.ibm.xsp.extlib.model.ObjectDataSource
,但这两种类型均不适用于以下xml:
<xp:inputText
id="input"
value="${compositeData.dsn[compositeData.fieldName]}"
>
</xp:inputText>
AbstractDocumentMapModel
public abstract class AbstractMapModel implements Serializable, DataObject {
private static final long serialVersionUID = 1L;
private Map<Object, Object> values;
public Class<?> getType(final Object key) {
Class<?> result = null;
if (getValues().containsKey(key)) {
Object value = getValues().get(key);
if (value != null) {
result = value.getClass();
}
}
return result;
}
protected Map<Object, Object> getValues() {
if (values == null) {
values = new HashMap<Object, Object>();
}
return values;
}
public Object getValue(final Object key) {
return getValues().get(key);
}
public boolean isReadOnly(final Object key) {
return false;
}
public void setValue(final Object key, final Object value) {
getValues().put(key, value);
}
}
public abstract class AbstractDocumentMapModel extends AbstractMapModel {
private static final long serialVersionUID = 1L;
private String unid;
public AbstractDocumentMapModel() {
String documentId = ExtLibUtil.readParameter(FacesContext
.getCurrentInstance(), "id");
if (StringUtil.isNotEmpty(documentId)) {
load(documentId);
}
}
protected abstract String getFormName();
public String getUnid() {
return unid;
}
public void setUnid(String unid) {
this.unid = unid;
}
public void load(final String unid) {
setUnid(unid);
Document doc = null;
try {
if (StringUtil.isNotEmpty(getUnid())) {
doc = ExtLibUtil.getCurrentDatabase().getDocumentByUNID(
getUnid());
DominoDocument wrappedDoc = DominoDocument.wrap(doc
.getParentDatabase().getFilePath(), // databaseName
doc, // Document
null, // computeWithForm
null, // concurrencyMode
false, // allowDeleteDocs
null, // saveLinksAs
null // webQuerySaveAgent
);
for (Object eachItem : doc.getItems()) {
if (eachItem instanceof Item) {
Item item = (Item) eachItem;
String itemName = item.getName();
if (!("$UpdatedBy".equalsIgnoreCase(itemName) || "$Revisions"
.equalsIgnoreCase(itemName))) {
setValue(item.getName(), wrappedDoc.getValue(item
.getName()));
}
DominoUtil.incinerate(eachItem);
}
}
}
} catch (Throwable t) {
t.printStackTrace();
} finally {
DominoUtil.incinerate(doc);
}
}
protected boolean postSave() {
return true;
}
protected boolean querySave() {
return true;
}
public boolean save() {
boolean result = false;
if (querySave()) {
Document doc = null;
try {
if (StringUtil.isEmpty(getUnid())) {
doc = ExtLibUtil.getCurrentDatabase().createDocument();
setUnid(doc.getUniversalID());
doc.replaceItemValue("Form", getFormName());
} else {
doc = ExtLibUtil.getCurrentDatabase().getDocumentByUNID(
getUnid());
}
for (Entry<Object, Object> entry : getValues().entrySet()) {
String itemName = entry.getKey().toString();
doc.replaceItemValue(itemName, DominoUtil
.toDominoFriendly(entry.getValue()));
}
if (doc.save()) {
result = postSave();
}
} catch (Throwable t) {
t.printStackTrace();
} finally {
DominoUtil.incinerate(doc);
}
}
return result;
}
public class IssueModel extends AbstractDocumentMapModel implements
Serializable {
private static final long serialVersionUID = 1L;
@Override
protected String getFormName() {
return "frmIssue";
}
@Override
protected boolean querySave() {
return super.querySave();
}
@Override
public boolean isReadOnly(final Object key) {
boolean result = super.isReadOnly(key);
/**
* Implement read only logic here as follows
*
* if ("jobTitle".equalsIgnoreCase((String) key)) { if
* (!ExtLibUtil.getXspContext().getUser().getRoles().contains("[HR]")) {
* result = true; } }
*/
return result;
}
}
ccFieldset
<?xml version="1.0" encoding="UTF-8"?>
<xp:view
xmlns:xp="http://www.ibm.com/xsp/core"
>
<div
class="form-group"
>
<xp:label
id="label"
for="input"
value="${compositeData.label.text}"
>
<xp:this.styleClass><![CDATA[${javascript:styleClass = "control-label col-" + compositeData.sz + "-" + compositeData.label.columns;
return styleClass;}]]></xp:this.styleClass>
</xp:label>
<xp:div>
<xp:this.styleClass><![CDATA[${javascript:styleClass = "col-" + compositeData.sz + "-" + compositeData.input.columns;
return styleClass;}]]></xp:this.styleClass>
<xp:inputText
id="input"
>
<xp:this.value><![CDATA[${javascript:"#{"+compositeData.BindTo+"}"}]]></xp:this.value>
<xp:this.styleClass><![CDATA[${javascript:styleClass = "input-" + compositeData.sz;
return styleClass;}]]></xp:this.styleClass>
</xp:inputText>
</xp:div>
</div>
</xp:view>
xpage中的工作字段
<div
class="form-group"
>
<xp:label
value="Database"
id="database_Label1"
for="database1"
styleClass="col-sm-2 control-label"
>
</xp:label>
<div
class="col-sm-6"
>
<xp:inputText
value="#{issue.Database}"
id="database1"
styleClass="input-sm"
>
</xp:inputText>
</div>
</div>
<xc:fieldset sz="md">
<xc:this.input>
<xc:input
columns="10"
bindTo="issue.Database"
>
</xc:input>
</xc:this.input>
<xc:this.label>
<xc:label
columns="2"
text="test"
>
</xc:label>
</xc:this.label>
</xc:fieldset>
未在xpage中使用ccFieldset
<div
class="form-group"
>
<xp:label
value="Database"
id="database_Label1"
for="database1"
styleClass="col-sm-2 control-label"
>
</xp:label>
<div
class="col-sm-6"
>
<xp:inputText
value="#{issue.Database}"
id="database1"
styleClass="input-sm"
>
</xp:inputText>
</div>
</div>
<xc:fieldset sz="md">
<xc:this.input>
<xc:input
columns="10"
bindTo="issue.Database"
>
</xc:input>
</xc:this.input>
<xc:this.label>
<xc:label
columns="2"
text="test"
>
</xc:label>
</xc:this.label>
</xc:fieldset>
确保传递给自定义控件的对象符合以下条件之一:
数据库
属性,则对象应(至少)具有一个getDatabase
方法,该方法返回数据库
属性的当前值;如果属性不是只读的,则该类还应具有接受新值的setDatabase
方法com.ibm.xsp.model.DataObject
接口。此接口要求您实现的通用getValue
和setValue
方法将分别用于检索和更新任何属性的值,包括数据库
com.ibm.jscript.types.FBSObject
的一个实例。这是在运行时解析SSJS字符串时,所有SSJS对象文本({}
)成为的底层Java类。小心在托管bean中使用这种类型,因为这些对象不是object
但是请记住,在
faces config.xml
中将类声明为托管bean只“管理”变量名和作用域。。。这个声明实际上并没有使Java类成为bean。除非它符合标准,否则它不是豆子。如果它确实符合bean约定,那么不管您是否将其声明为托管bean,它都是bean。这种区别在XPages社区中引起了很多混乱,因此我只想在本文中再次说明这一点。诀窍是将一个字符串作为您想要使用的EL的参数进行传递。假设您有一个参数bindTo as String,其值为myBean.Color
<xp:this.value><![CDATA[${javascript:"#{"+compositeData.BindTo+"}"}]]></xp:this.value>
美元将首先计算并用实际值替换合成数据。方法之美:适用于任何EL。文档Bean等,因此您的自定义控件不需要对其容器进行任何假设
因此,您可以使用各种绑定调用组件:
<xc:myComponent BindTo="document1.subject"></xc:myComponent>
<xc:myComponent BindTo="viewScope.someVariable"></xc:myComponent>
<xc:myComponent BindTo="myBean.Color"></xc:myComponent>
让我们知道这对你是如何起作用的 我从未尝试过您正在尝试的内容,但我建议您尝试使用“高级”下的自定义绑定。您还可以尝试首先将compositeDate设置为作用域变量,然后尝试动态绑定元素。第一个字符不能使用大写字母。在测试中,我不得不在
value=“${compositeData.dsn[compositeData.fieldName]}”行中使用“#”而不是“$”
。但是,在这两个更改中,您的代码对我都起到了作用。我在自定义控件中使用了动态绑定,使用这种语法时没有任何问题:value=“#{compositeData.dataSource[compositeData.fieldName]}”
。有关示例,请参见此处:。顺便说一句:我永远不会调用我的字段名数据库
,因为还有一个名为数据库
的全局SSJS对象。从理论上讲,它可以工作,但我喜欢站在安全的一边。@MarkLeusink我刚刚选择了数据库,因为这是一个我已经绑定的领域,并且正在按常规工作。我要换一个。问题的一部分可能是,我用于后端的bean使用了@TimTripcony在NotesIn9中演示的AbstractDocumentMapModel
和AbstractMapModel
。可能每个属性没有传统的getter和setter,绑定就不起作用了。My bean基本上是从NotesIn9演示文稿中直接剥离出来的,所以它符合1、2和3。您可以识别AbstractDocumentMapModel
。因此,我将我的类型设置为.AbstractDocumentMapModel
,并且在编译时这样做之后,我得到了错误未知属性dsn。它没有在标记xc上定义:input按照您的建议将类型更改为object
,可以修复错误,但实际上不会将编辑框绑定到my bean。谢谢您的回复。一定有什么中间步骤我做错了。它的计算结果似乎为空-该字段不可编辑且未填充。添加显示参数的计算字段,以便查看是否有效。并更新问题以添加您当前的代码尝试。您的参数值是多少?抱歉,响应太慢。东海岸天气。在我解决了几个问题后(compositeData.bindTo
->compositeData.input.bindTo