Grails 动态渲染 map-injected g :select

标签 grails hashmap html-select gsp

我有以下 Grails (2.3.6) Controller :

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

  • 换句话说,如果 widgetMap (上面,在 Controller 中)在运行时看起来像这样:
    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> child :“颜色”和“宠物”。当您选择“颜色”时,您应该会看到一个项目符号 (<ul>) 列表,其中列举了“红色”、“蓝色”、“绿色”;如果您选择“宠物”,您会看到之前的任何列表都被清除,然后显示“狗”和“猫”的列表。因此,从下拉列表中进行任何新选择都应清除当前显示的列表,并为该选项在 map 中的相应键显示正确的列表。

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

    最佳答案

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

  • 将整个 map 传递回客户端并将值存储在 javascript 值中。我不喜欢这个,因为它不能很好地扩展。在您的示例中,每个列表中只有几个键和几个值,但这可能会增长得很快,而且我认为您不必将所有这些数据存储在客户端的内存中。
  • 进行后续的 Ajax 调用以简单地返回每个键的列表。这可以通过监听 change 来完成。事件,然后将 div 的内容替换为 GSP 呈现的模板。我更喜欢这个选项,因为它可以扩展。当然,它会向服务器发出更多调用,但每次调用的数据量很少,并且随着初始页面加载的减少,您的用户体验实际上会整体得到改善。

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

    关于Grails 动态渲染 map-injected g :select,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27690290/

    相关文章:

    javascript - 验证具有未知 id 和公共(public)类的动态 HTML Select 的空值

    grails - 什么时候在Grails框架的标签属性值中使用表达式$ {}?

    grails - 如何列出所有旧版本的 Grails 插件?

    java - 如何迭代(并更改)作为另一个集合的值的集合

    indexing - 为什么索引 HashMap 不返回引用?

    javascript - 无法根据选择框中的选项值更改缩略图产品图像

    grails发布插件错误 "class not found loading plugin resource [spring.resources]"

    Grails:从另一个标签库中调用一个标签库

    java - 通过传递键列表从 HashMap 中删除键 - Java API 方法或实用程序?

    jquery - 使用浏览器后退按钮导航时,下拉列表选定的值不会返回