Grails动态渲染地图注入g:选择

时间:2014-12-29 13:58:06

标签: grails hashmap html-select gsp

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

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

以下GSP:

<!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地图中的每个关键字,请在下拉列表<option/>
  • 中显示<select/>
  • 当用户选择其中一个&lt; option/>时(或首次使用默认选项加载页面时),<div id="widgetMapping">部分应填充<ul>列表,其中列表中的每个<li>对应于所选小部件映射到的List<String>中的一个元素

换句话说,如果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中,我希望看到<select>有2个<option>个孩子:&#34; 颜色&#34;和&#34; 宠物&#34;。选择&#34; Colors&#34;你应该看到一个项目符号(<ul>)列表&#34; 红色&#34;,&#34; 蓝色&#34;,&# 34; 绿色&#34 ;;如果你选择&#34; Pets&#34;你会看到任何以前的列表清除,然后显示&#34; Dog &#34;和&#34; Cat &#34;取而代之。因此,从下拉列表中进行任何新选择都应清除当前显示的列表,并在地图中显示该选项的相应键的正确列表。

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

1 个答案:

答案 0 :(得分:0)

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

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

  2. 进行后续Ajax调用,只返回每个键的列表。这可以通过在下拉列表上侦听change事件,然后用GSP渲染模板替换div的内容来实现。随着它的扩展,我更喜欢这个选项。当然,它会对服务器进行更多调用,但每次调用的数据量很小,而且您的用户体验实际上会有所改善,因为初始页面加载会减少。

  3. 控制器:

    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的文档和网上的几个例子,所以如果你认为你想做一些不同的事情,我建议你四处看看。