【问题标题】:Grails dynamic rendering of map-injected g:select地图注入 g:select 的 Grails 动态渲染
【发布时间】:2014-12-29 13:58:06
【问题描述】:

我有以下 Grails (2.3.6) 控制器:

class WidgetController {
    def index() {
        Map<String, List<String>> widgetMap = getSomehow()
        render (
            view: "widgets",
            model: [ widgetMapping: widgetMap ]
        )
    }
}

以及以下普惠制:

<!DOCTYPE html>
<html>
<head>
    <!-- Omitting a bunch of stuff for brevity -->
</head>
<body>
    <h3>Widget Mappings</h3>

    <g:select name="widgetMapping" from="${widgetMapping}"/>
    <div id="widgetMapping">
    </div>
</body>
</html>

我正在努力完成以下工作:

  • 对于widgets 映射中的每个键,在下拉列表&lt;select/&gt; 中显示一个&lt;option/&gt;
  • 当用户选择其中一个 option/>s(或当页面首次加载默认选项时)时,&lt;div id="widgetMapping"&gt; 部分应填充&lt;ul&gt; 列表,其中每个&lt;li&gt; 在列表对应于List&lt;String&gt; 中所选小部件映射到的元素之一

换句话说,如果widgetMap(上面,在控制器中)在运行时看起来像这样:

Map<String, List<String>> widgetMap = []

List<String> colors = []
List<String> pets = []

colors << "Red"
colors << "Blue"
colors << "Green"

pets << "Dog"
pets << "Cat"

widgetMap.put("Colors", colors)
widgetMap.put("Pets", pets)

...然后在呈现的 HTML 中,我希望看到一个带有 2 个&lt;option&gt; 孩子的&lt;select&gt;:“Colors”和“Pets”。当您选择“颜色”时,您应该会看到一个项目符号 (&lt;ul&gt;) 列表,其中列举了“Red”、“Blue”、“Green” ;如果您选择“宠物”,您会看到之前的所有列表都被清除,然后显示“Dog”和“Cat”的列表。因此,从下拉列表中进行任何新选择都应清除当前显示的列表,并为该选项在地图中的相应键显示正确的列表。

鉴于我上面的 GSP 代码,这种行为根本不会发生。关于我需要做什么的任何想法?

【问题讨论】:

  • GSP 不会单独完成这件事。你写过任何 Javascript 来完成你想要的吗?当你尝试这个时实际呈现的是什么?
  • 另一件事可能只是转录错误,您在 GSP 中引用了一个变量 widgetMapping,但您的控制器设置了一个模型变量 widgetMap。虽然纠正这一点会对您有所帮助,但仍不能解决您的全部问题。
  • 谢谢@rmlan - 是的,这是一个转录错误(请参阅我的更新)。另外,不,我还没有编写任何 JS 代码,因为我希望 Grails 可以开箱即用地提供类似的东西。我通过资产管道“安装”了 jQuery - 关于如何使用 jQuery 完成此行为的任何想法?或者甚至只是原始的 JS?再次感谢!

标签: grails hashmap html-select gsp


【解决方案1】:

根据您提到的内容,您有几个不同的选择。

  1. 将整个地图传递回客户端并将值存储在 javascript 值中。我不喜欢这个,因为它不能很好地扩展。在您的示例中,每个列表中只有几个键和几个值,但这可能会增长得很快,而且我认为您不必将所有这些数据存储在客户端的内存中。

  2. 进行后续的 Ajax 调用以简单地返回每个键的列表。这可以通过在下拉列表中侦听change 事件来完成,然后将 div 的内容替换为 GSP 呈现的模板。我更喜欢这个选项,因为它可以扩展。当然,它会向服务器发出更多调用,但每次调用的数据量很少,并且随着初始页面加载的减少,您的用户体验实际上会整体得到改善。

控制器:

class WidgetController {
    def index() {
        def widgetKeys = getSomehow()
        render (
            view: "widgets",
            model: [ widgets: widgetKeys ]
        )
    }

    def widgetList (String key) {
        def widgetList = getSomehow(key)
        render (
            template: "widgetTemplate",
            model: [ widgetList: widgetList ]
        )
    }
}

模板:

<ul>
    <g:each in="${widgetList}">
    <li>${it}</li>
    </g:each>
</ul>

Javascript:

$(function () {
    $('#selectId').on('change', function(){
        var select = this;
        $.ajax({
            url: 'widgetList', //might have to play with this so it is not hardcoded
            data: { 'key': select.value },
            success: function (list) {
                $('#widgetMapping').html(list);
            } 
        });
    })
});

我不保证这会让你得到你想要的,但这至少应该让你走上正轨。有大量的 JQuery 文档和网络上的几个示例,所以如果您认为自己想做一些不同的事情,我建议您四处看看。

【讨论】:

    猜你喜欢
    • 2015-11-09
    • 1970-01-01
    • 2022-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-17
    • 1970-01-01
    相关资源
    最近更新 更多