g:select 和 jQuery 处理程序的 Grails 注入

Grails injection of g:select and jQuery handler

我有以下 Grails (2.3.6) POGO:

class Pet {
    Long id
    String name
    PetType type
}

以及以下控制器:

class PetController {
    def index() {
        List<Pet> pets = PetLoader.loadAllPets()
        render(
            view: "listPets",
            model: [
                pets: pets
            ]
        )
    }

    def loadPet() {
        Long petId = params.petId   // Pet#id
        // Do stuff with the 'petId'.
    }
)

并在各自的正文中 listPets.gsp:

<body>
    <h1>Select a pet to edit below:</h1>

    <g:select id="pets"
        name="pets"
        from="${pets}"
        value="${pet.name}"
        optionKey="id" />

    <g:javascript>
        var ajaxAction = "${createLink(controller:'pet',action:'loadPet')}"
        $("#pets").on('change', function() {
            $.get(
                url: ajaxAction,
                data: $("#pets").val(),
                success: function(data, status) {
                    alert("Success!\n" + data);
                },
                dataType: "json"
            );
        });
    </g:javascript>
</body>

当我运行这段代码时,我得到一个空的 <g:select>,显然 injected/configured 不正确。我想做的是:

  1. 当页面加载时,整个 users 列表被注入到 <select id="pets"> 下拉列表中,并显示 Pet#name 字符串作为选项文本;然后
  2. 当用户 select 从下拉菜单(在 UI 中)创建新的 Pet 时,jQuery 处理程序会触发对 loadPet 的异步调用;然后
  3. loadPet 中,我需要通过 params 对象访问下拉列表中 selected 值的 Pet#id,这样我就可以做后端具有该宠物 ID 的其他内容

我很难在这里透过树木看到森林。我确定我搞砸了 <g:select> 标签。但我可能还需要对控制器 and/or jQuery 脚本进行更改。所以我问:我需要对我的代码进行哪些更改,以便 select 填充 Pet#name,但是,当从 jQuery 调用 loadPets 时,我可以访问从 params?

Pet#id

稍微修改一下您的代码,这里有一个示例(我相信)可以达到您的预期。以下是主要变化:

  1. g:select内,使用optionValueoptionKey来控制 显示字符串和基础 <option> 值。欲了解更多详情和 示例,请参阅:http://grails.org/doc/latest/ref/Tags/select.html
  2. 您的 jQuery 代码使用 .get() shorthand,但 .ajax() 参数语法。 两者都可以工作,但函数参数有所不同。看: http://api.jquery.com/jquery.get/
  3. 我将 CDN link 添加到 jQuery。这对于快速测试很有用,但还有多种其他方法可以包含 jQuery 库(您可能已经在项目中配置了它)
  4. createLinkraw()包裹,确保产生的URL不被转义。

更新代码:

PetPetController

没有变化

listPets.gsp

<!DOCTYPE html>
<html>
  <head>
  <meta name="layout" content="main"/>
  <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
</head>
<body>
    <h1>Select a pet to edit below:</h1>

    <g:select id="pets"
        name="pets"
        from="${pets}"
        optionKey="id"
        optionValue="name" />

    <g:javascript>
        var ajaxAction = '${raw(createLink(controller:'pet',action:'loadPet'))}';
        $("#pets").on('change', function() {
            $.ajax({
                url: ajaxAction,
                data: { petId: $("#pets").val() },
                success: function(data, status) {
                    alert("Success!\n" + data);
                }
            });
        });
    </g:javascript>

</body>
</html>