具有动态名称的 Servlet 属性
Servlet property with dynamic name
我创建了一个自定义 Dojo 1.9 小部件,它旨在成为一个通用的组合框,我可以在其中以声明方式插入任何带有下拉列表的 dojo 小部件,因此在我的 jsp 页面中.
这是一个 dojo 组合框的示例,我希望用此小部件替换它:
<div data-dojo-type="dojo/store/Memory"
data-dojo-id="machineNameStore"
data-dojo-props="<s:property value='%{getNameJsonString()}'/>"></div>
<s:set name="MachineName" value="machineSearchView.name"
scope="request"></s:set>
<div data-dojo-type="dijit/form/ComboBox"
data-dojo-props="store:machineNameStore, searchAttr:'name', value:'${MachineName}'"
name="machineSearchView.name" id="machineSearchView.name" />
这是我的小部件的 html 代码:
<div class="${baseClass}">
<div data-dojo-type="dojo/store/Memory" data-dojo-attach-point="memoryNode"
data-dojo-id="${dataStoreId}"
data-dojo-props="${dataSourceData}"></div>
<s:set name="${fieldName}" value="${searchViewFieldName}" scope="request"> <s:set>
<div data-dojo-type="${dropDownType}" data-dojo-attach-point="dropDownNode"
data-dojo-props="store:${dataStoreId}, searchAttr:'${searchAttrName}', value: '${fieldName}'"
name="${searchViewFieldName}" id="${searchViewFieldName}" ></div>
</div>
这是我的小部件的 javascript 代码:
/**
* Javascript for ExpandableSearchComponent
*/
define([ "dojo/_base/declare", "dijit/_WidgetBase", "dijit/_TemplatedMixin",
"dojo/text!./templates/ExpandableSearchComponent.html",
"dijit/_WidgetsInTemplateMixin", "dojo/store/Memory",
"dijit/form/ComboBox", "dijit/form/Select",
"dijit/form/FilteringSelect"
], function(declare, _WidgetBase, _TemplatedMixin, template,
_WidgetsInTemplateMixin, Memory) {
return declare([ _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin ], {
templateString : template,
fieldName : "",
dataSourceData : "",
dropDownType : "",
searchAttrName : "",
searchViewFieldName : ""
});
});
这就是在页面中调用小部件的方式:
<div data-dojo-type="js/widgets/ExpandableSearchComponent"
data-dojo-id="operatingSystemStore"
data-dojo-props="dataSourceData: '<s:property value='%{getNameJsonString()}'/>',
fieldName:'machineName' , dataStoreId: 'machineNameDataStore',
dropDownType: 'dijit/form/ComboBox', searchAttrName: 'name',
searchViewFieldName: 'machineSearchView.name'"></div>
这对大约 90% 有效,让我希望我能使它完全正常工作。在我开始对此进行扩展以使其具有我想要的外观之前,我现在的大错误是下拉值元素的问题。
如您所见,我有一个请求范围的 servlet 属性,它采用我正在搜索的机器的名称并将其传递到我的组合框的值中。我需要能够将我的 Dojo Widget 的多个实例添加到我的页面,所以我需要能够使这个 servlet 属性 的名称成为一个变量。但是,在我的 Dojo 组合框值中,我需要使用我创建的这个 属性 作为 dojo 属性 的值。所以我基本上想说 "insert a JSP property into this page with name X",其中 X = ${fieldName}
由 Dojo 生成。但是,这意味着在将 servlet 发送到页面并由 Dojo 处理后生成一个 servlet。
我检查了其他答案,例如 struts2 get property with dynamic value in jsp 和其中的相关问题,但问题是这些答案都使用 <s:text>
或 <s:property>
,但 Dojo 不能解析位于 data-dojo-props
标记中的小部件。如果我只是尝试用另一个 ${}
包围 ${fieldName}
,那将无法正确解析。
有没有办法解决这个问题?
评论中要求的澄清:
- 期望的行为:我想在编写第 4 个代码片段时使用 Dojo 生成第一个 HTML 代码片段。
- 可重现的问题:我得到了大部分正确的片段,但是当 ${fieldName} 被 Dojo 解析时,它变成了 machineName,这正是我在 s:set 中想要的,但是在 Combobox 中,当输入它作为值,它被写为字符串文字 machineName。我想调整我的第二个和第三个片段,而不是
value: 'machineName'
,它读取 value:'${machineName}'
就像在第一个片段中一样,所以它检索 s:set.[=48 中设置的请求范围参数=]
实质是我的 struts2 操作中 machineSearchView.name 的当前值应该在组合框中预选。这就是我想要实现的目标。但是,我还想在同一个 JSP 页面中使用该元素的多个实例,我认为这意味着我不能让它们都具有相同的名称。
经过一些测试,我找到了解决问题的方法。实际上,我已经将 servlet 转换逻辑分离到页面本身,而不是在 Dojo 中尝试这样做。
html:
<div class="${baseClass}">
<div data-dojo-type="dojo/store/Memory" data-dojo-attach-point="memoryNode"
data-dojo-id="${dataStoreId}"
data-dojo-props="${dataSourceData}"></div>
<div data-dojo-type="${dropDownType}" data-dojo-attach-point="dropDownNode"
data-dojo-props="store:${dataStoreSearchProp}, name: '${searchViewFieldName}', value: '${valueSearchProp}'" name="${searchViewFieldName}" id="${searchViewFieldName}" ></div>
</div>
Javascript:
/**
* Javascript for ExpandableSearchComponent
*/
define([ "dojo/_base/declare", "dijit/_WidgetBase", "dijit/_TemplatedMixin",
"dojo/text!./templates/ExpandableSearchComponent.html",
"dijit/_WidgetsInTemplateMixin", "dojo/store/Memory", "dojo/parser",
"dijit/form/ComboBox", "dijit/form/Select",
"dijit/form/FilteringSelect"
], function(declare, _WidgetBase, _TemplatedMixin, template,
_WidgetsInTemplateMixin, Memory, parser) {
return declare([ _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin ], {
templateString : template,
fieldName : "",
searchProps : "",
dataSourceData : "",
dataStoreSearchProp: "",
NameSearchProp:"",
valueSearchProp:"",
dropDownType : "",
searchViewFieldName : "",
});
});
如何使用:
<s:set var='machineName' value='machineSearchView.name'
scope='request'>
</s:set>
<div data-dojo-type="js/widgets/ExpandableSearchComponent"
data-dojo-id="operatingSystemStore"
data-dojo-props="dataSourceData: '<s:property value='%{getNameJsonString()}'/>', dataStoreSearchProp: 'machineNameDataStore', valueSearchProp: '${machineName}', dataStoreId:'machineNameDataStore', dropDownType: 'dijit/form/ComboBox', searchViewFieldName: 'machineSearchView.name'"></div>
</td>
但是,由于业务沟通不畅,这不是我最终要采用的解决方案。
我创建了一个自定义 Dojo 1.9 小部件,它旨在成为一个通用的组合框,我可以在其中以声明方式插入任何带有下拉列表的 dojo 小部件,因此在我的 jsp 页面中.
这是一个 dojo 组合框的示例,我希望用此小部件替换它:
<div data-dojo-type="dojo/store/Memory"
data-dojo-id="machineNameStore"
data-dojo-props="<s:property value='%{getNameJsonString()}'/>"></div>
<s:set name="MachineName" value="machineSearchView.name"
scope="request"></s:set>
<div data-dojo-type="dijit/form/ComboBox"
data-dojo-props="store:machineNameStore, searchAttr:'name', value:'${MachineName}'"
name="machineSearchView.name" id="machineSearchView.name" />
这是我的小部件的 html 代码:
<div class="${baseClass}">
<div data-dojo-type="dojo/store/Memory" data-dojo-attach-point="memoryNode"
data-dojo-id="${dataStoreId}"
data-dojo-props="${dataSourceData}"></div>
<s:set name="${fieldName}" value="${searchViewFieldName}" scope="request"> <s:set>
<div data-dojo-type="${dropDownType}" data-dojo-attach-point="dropDownNode"
data-dojo-props="store:${dataStoreId}, searchAttr:'${searchAttrName}', value: '${fieldName}'"
name="${searchViewFieldName}" id="${searchViewFieldName}" ></div>
</div>
这是我的小部件的 javascript 代码:
/**
* Javascript for ExpandableSearchComponent
*/
define([ "dojo/_base/declare", "dijit/_WidgetBase", "dijit/_TemplatedMixin",
"dojo/text!./templates/ExpandableSearchComponent.html",
"dijit/_WidgetsInTemplateMixin", "dojo/store/Memory",
"dijit/form/ComboBox", "dijit/form/Select",
"dijit/form/FilteringSelect"
], function(declare, _WidgetBase, _TemplatedMixin, template,
_WidgetsInTemplateMixin, Memory) {
return declare([ _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin ], {
templateString : template,
fieldName : "",
dataSourceData : "",
dropDownType : "",
searchAttrName : "",
searchViewFieldName : ""
});
});
这就是在页面中调用小部件的方式:
<div data-dojo-type="js/widgets/ExpandableSearchComponent"
data-dojo-id="operatingSystemStore"
data-dojo-props="dataSourceData: '<s:property value='%{getNameJsonString()}'/>',
fieldName:'machineName' , dataStoreId: 'machineNameDataStore',
dropDownType: 'dijit/form/ComboBox', searchAttrName: 'name',
searchViewFieldName: 'machineSearchView.name'"></div>
这对大约 90% 有效,让我希望我能使它完全正常工作。在我开始对此进行扩展以使其具有我想要的外观之前,我现在的大错误是下拉值元素的问题。
如您所见,我有一个请求范围的 servlet 属性,它采用我正在搜索的机器的名称并将其传递到我的组合框的值中。我需要能够将我的 Dojo Widget 的多个实例添加到我的页面,所以我需要能够使这个 servlet 属性 的名称成为一个变量。但是,在我的 Dojo 组合框值中,我需要使用我创建的这个 属性 作为 dojo 属性 的值。所以我基本上想说 "insert a JSP property into this page with name X",其中 X = ${fieldName}
由 Dojo 生成。但是,这意味着在将 servlet 发送到页面并由 Dojo 处理后生成一个 servlet。
我检查了其他答案,例如 struts2 get property with dynamic value in jsp 和其中的相关问题,但问题是这些答案都使用 <s:text>
或 <s:property>
,但 Dojo 不能解析位于 data-dojo-props
标记中的小部件。如果我只是尝试用另一个 ${}
包围 ${fieldName}
,那将无法正确解析。
有没有办法解决这个问题?
评论中要求的澄清:
- 期望的行为:我想在编写第 4 个代码片段时使用 Dojo 生成第一个 HTML 代码片段。
- 可重现的问题:我得到了大部分正确的片段,但是当 ${fieldName} 被 Dojo 解析时,它变成了 machineName,这正是我在 s:set 中想要的,但是在 Combobox 中,当输入它作为值,它被写为字符串文字 machineName。我想调整我的第二个和第三个片段,而不是
value: 'machineName'
,它读取value:'${machineName}'
就像在第一个片段中一样,所以它检索 s:set.[=48 中设置的请求范围参数=] 实质是我的 struts2 操作中 machineSearchView.name 的当前值应该在组合框中预选。这就是我想要实现的目标。但是,我还想在同一个 JSP 页面中使用该元素的多个实例,我认为这意味着我不能让它们都具有相同的名称。
经过一些测试,我找到了解决问题的方法。实际上,我已经将 servlet 转换逻辑分离到页面本身,而不是在 Dojo 中尝试这样做。
html:
<div class="${baseClass}">
<div data-dojo-type="dojo/store/Memory" data-dojo-attach-point="memoryNode"
data-dojo-id="${dataStoreId}"
data-dojo-props="${dataSourceData}"></div>
<div data-dojo-type="${dropDownType}" data-dojo-attach-point="dropDownNode"
data-dojo-props="store:${dataStoreSearchProp}, name: '${searchViewFieldName}', value: '${valueSearchProp}'" name="${searchViewFieldName}" id="${searchViewFieldName}" ></div>
</div>
Javascript:
/**
* Javascript for ExpandableSearchComponent
*/
define([ "dojo/_base/declare", "dijit/_WidgetBase", "dijit/_TemplatedMixin",
"dojo/text!./templates/ExpandableSearchComponent.html",
"dijit/_WidgetsInTemplateMixin", "dojo/store/Memory", "dojo/parser",
"dijit/form/ComboBox", "dijit/form/Select",
"dijit/form/FilteringSelect"
], function(declare, _WidgetBase, _TemplatedMixin, template,
_WidgetsInTemplateMixin, Memory, parser) {
return declare([ _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin ], {
templateString : template,
fieldName : "",
searchProps : "",
dataSourceData : "",
dataStoreSearchProp: "",
NameSearchProp:"",
valueSearchProp:"",
dropDownType : "",
searchViewFieldName : "",
});
});
如何使用:
<s:set var='machineName' value='machineSearchView.name'
scope='request'>
</s:set>
<div data-dojo-type="js/widgets/ExpandableSearchComponent"
data-dojo-id="operatingSystemStore"
data-dojo-props="dataSourceData: '<s:property value='%{getNameJsonString()}'/>', dataStoreSearchProp: 'machineNameDataStore', valueSearchProp: '${machineName}', dataStoreId:'machineNameDataStore', dropDownType: 'dijit/form/ComboBox', searchViewFieldName: 'machineSearchView.name'"></div>
</td>
但是,由于业务沟通不畅,这不是我最终要采用的解决方案。