具有动态名称的 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},那将无法正确解析。

有没有办法解决这个问题?


评论中要求的澄清:

  1. 期望的行为:我想在编写第 4 个代码片段时使用 Dojo 生成第一个 HTML 代码片段。
  2. 可重现的问题:我得到了大部分正确的片段,但是当 ${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>

但是,由于业务沟通不畅,这不是我最终要采用的解决方案。