我已經閱讀了大量關於在自定義控件中動態綁定字段的優秀帖子和文章,但他們都假設了文檔數據源。將自定義控件中的編輯框動態綁定到託管bean
我想允許管理bean數據源的可能性。我試過屬性類型設置爲com.ibm.xsp.model.DataSource
或com.ibm.xsp.extlib.model.ObjectDataSource
既不具有以下XML的工作:
<xp:inputText
id="input"
value="${compositeData.dsn[compositeData.fieldName]}"
>
</xp:inputText>
在使用控制我已經通過了在自定義的數據,像這樣:
<xc:input
dsn="#{issue}"
fieldName="Database"
>
</xc:input>
對於我測試目的,我有一個名爲issue
的託管bean,我打電話給我的字段Database
。我通常會綁定到#{issue.Database}
,但我無法弄清楚如何動態地做到這一點。理想情況下,我也想支持文檔數據源,但是如果我不能這樣做,那麼我需要綁定到託管bean。
編輯:問題似乎是數組符號。如果我硬編碼我的價值#{issue.Database}
它的作品,但如果我硬編碼到它失敗。所以問題是如果有一個替代表示符號。我今天沒有時間,但是我想知道是不是將dsn和fieldName分開,如果我只是將#{issue}傳入dsn並使用它作爲我的數據綁定可以工作?當我有機會時,我會嘗試。
Edit2:因爲它看起來問題可能與我正在使用的bean有關,所以我會在這裏發佈代碼。
AbstractMapModel
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);
}
}
AbstractDocumentMapModel
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;
}
}
IssueModel
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工作領域中的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>
不工作ccFieldset
<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>
我從來沒有嘗試過你正在嘗試的,但我建議你嘗試使用「高級」下的自定義綁定。您也可以先嚐試將compositeDate設置爲作用域變量,然後嘗試動態綁定該元素。 –
如果你有一個具有getters和setter的普通Java bean,那麼fieldName必須是「數據庫」。它不適用於大寫字母作爲第一個字符。在我的測試中,我不得不在「value =」$ {compositeData.dsn [compositeData.fieldName]}「'行中使用」#「而不是」$「。但是,這兩個變化你的代碼爲我工作。 –
我已經在自定義控件中使用動態綁定,沒有任何問題使用這種語法:'value =「#{compositeData.dataSource [compositeData.fieldName]}」'。有關示例,請參閱此處:http://bootstrap4xpages.com/bs4xp/demos.nsf/reusableFields.xsp。順便說一句:我永遠不會打電話給我的字段名稱「數據庫」,因爲還有一個叫做'database'的全局SSJS對象。理論上它可以工作,但我喜歡保持安全。 –