更新从另一个控制器呈现的视图内的模板

时间:2014-06-12 08:58:41

标签: ajax grails render gsp grails-controller

我正在寻找一种方法来刷新从另一个控制器渲染的视图中的模板,而不是模板的控制器,我的意思是:

我有两个控制器 AdminController &的 UserController中即可。两个gsps / admin / listUsers &的 /用户/ _searchResult

然后想要渲染模板 _searchResult 内的视图 listUsers ,并且可以。

现在,我想刷新模板 _searchResult ,但无法找到方法。我试着打电话给render(view:"/admin/listUsers", template:"/user/_searchResult", model:[searchResult:result])


AdminController.groovy

@Secured(['ROLE_ADMIN'])
def listUsers(){
    //...
}

UserController.groovy

@Secured(['ROLE_ADMIN'])
def search(){
    //search users for the givven params and send result by chain if there's an action or update a template if it's needed
    //in my case this method need to update the template _searchResult
}

@Secured(['ROLE_ADMIN'])
def searchResult(){
    //...
    [searchResult:result]
}

listUsers.gsp

//...
<formRemote name="searchForm" url="[action:"search", controller:"user"]">
     //Some fields for the search
     //I need to place here some hidden inputs to send which 
     //template i want to update or action to redirect
</formRemote>
<g:render template="/user/_searchResult"/>

//...

_searchResult.gsp

//Just itterate and print the search result in a table

我希望我已正确解释了这个问题,谢谢!

2 个答案:

答案 0 :(得分:3)

我不认为我完全理解你的问题,但我认为你混淆的原因是你命名的方式并不遵循常规惯例而你没有使用正确的工具来完成工作。让我解释一下......

控制器上的方法称为Actions。它们将一些数据(模型)发送到要呈现为HTML的视图。视图可以由称为模板的较小的可重用片段组成。 (对不起,如果我听起来像是在这里屈尊俯就,但我只是想确保我们都在同一页上。)

现在,你所谓的templateA实际上是一个视图,而不是一个模板。你是正确的,templateA(你的View)可以调用templateB来呈现一些标记,但是让templateB尝试在另一个Controller上调用一个方法没有意义。事情并非如此。

如果在将模型发送到视图后需要执行某些逻辑,则需要使用标记库(http://grails.org/doc/latest/guide/theWebLayer.html#taglibs)。

总结一下,这是一个快速回顾。

  1. 请求只应调用一个Action,它只将模型发送到一个视图。
  2. 如果需要在控制器之间重用逻辑,请将该代码移至服务。
  3. 如果需要在视图之间重用标记,请将该标记移动到模板。
  4. 如果您在将模型发送到视图后想要执行逻辑,请使用标记库。
  5. 希望这会指出你正确的方向。

    --- 更新 ---

    好的,通过真实的代码我可以更好地看到你想要实现的目标。首先,当您使用<g:formRemote>标记时,您应该仔细阅读http://grails.org/doc/latest/ref/Tags/formRemote.html处的文档以了解它的作用。

    这里有两个独立的请求。第一个是浏览器的常规页面加载,由listUsers()操作处理。页面完成加载后,用户将输入搜索词并点击提交按钮。这将触发第二个ajax请求,该请求将由search()动作处理。此操作可以使用_searchResult.gsp模板呈现HTML表以显示搜索结果。当浏览器得到它时,它会将它插入到你告诉它使用<g:formRemote>标签的“更新”属性放置的DOM中。

    重要的是,从服务器的角度来看,这些是完全独立的2个独立请求。它们首先调用一个动作,然后将一个模型(一个包含一些数据的Map)发送到一个视图,该视图使用HTML呈现/合并数据并将其发送回浏览器。

    2之间的区别在于第一个是浏览器的完整页面加载,而对于第二个请求,浏览器只加载一小部分HTML(搜索结果表)并更新页面内容而不重新加载

    所以你的代码看起来更像......

    <强> AdminController.groovy

    @Secured(['ROLE_ADMIN'])
    def listUsers() {
        render(view:"/admin/listUsers")
    }
    

    <强> listUsers.gsp

    <g:formRemote name="searchForm" update="insertSearchResultsHere"
              url="[controller: 'user', action:'search']">
        <input name="searchTerm" type="text" />
    </g:formRemote>
    <div id="insertSearchResultsHere"></div>
    

    <强> UserController.groovy

    @Secured(['ROLE_ADMIN'])
    def search() {
        // use the search term to get a List<User>
        render(template: "/user/searchResult", model: [users: users])
    }
    

    <强> _searchResult.gsp

    <table>
        <g:each var="user" in="${users}">
            %{-- Iterate through your search results --}%
        </g:each>
    </table>
    

答案 1 :(得分:0)

我通过放置属性update并仅渲染模板来解决它:


<强> GSP:

<formRemote name="searchForm" url="[action:"search", controller:"user"]" update="divToUpdate">
     //Some fields for the search
</formRemote>

<div id="divToUpdate">
     <g:render template="/user/_searchResult"/>
</div>

<强>控制器:

def search(){
    render(template:"/user/_searchResult", model:[searchResult:result])
}

当我问这个问题时,我是Grails社区的新手,我对使用remoteFunction和使用remoteForm的标签感到困惑。但由于我没有阅读文档,我有这种困惑。所以在我的例子中,解决方案是搜索有关如何使用远程标签和渲染的文档。感谢@AndrewW给我指路。