Grails - 控制器和视图之间的通信

Posted

技术标签:

【中文标题】Grails - 控制器和视图之间的通信【英文标题】:Grails - communicating between controllers and views 【发布时间】:2011-09-10 10:28:42 【问题描述】:

我想知道如何从控制器中的列表中填充视图中的文本框,我一直在搜索示例,但还没有真正找到任何东西。我不确定如何从视图中准确地访问文本字段,就像在 Java 中一样,您可以做一些像 jTextField.getText() 这样简单的事情。我也想知道如何在我的文本框中抓取文本。

下面我将发布一些我正在做的示例代码。

控制器:

def loadFile = 
    def propFile = "c:/props.txt"
    def propMap = [:]
    def propList = []

    new File(propFile).eachLine  line ->
    def (key,value) = line.split(':').collect  it.trim() 
    propMap."$key" = "$value"

    if(propMap) 
    propList << propMap
    propMap = [:]
    




def saveFile = 
    //get contents of text box
    //over-write props.txt with new information

查看:

<g:textField name="properties"/>
<span class="menuButton"/><g:link action="loadFile" controller="myController">Load File</g:link>
<span class="menuButton"/><g:link action="saveFile" controller="myController">Save File</g:link> 

所以,我的问题似乎比较直截了当,当我想填充文本框并从中保存数据时,如何访问它?

.

.

.

编辑

在查看了你们提交的一些示例之后,我有最后一个问题。

为什么单击Load File 按钮时,以下代码的行为会有所不同?

<g:form controller="drive">
<g:textArea name="properties" value="$params.param1" rows="50" cols="6"/>
<br/>
<g:submitButton name="loadFile" value="Load File"/>
<g:submitButton name="saveFile" value="Save File"/>
</g:form>
<span class="menuButton"/><g:link action="loadFile" controller="drive">Load File</g:link>

单击处理loadFileg:submitButton 时,它会将我重定向到list gsp。但是,当我单击 menuButton 时,它会使用文件中的文本加载 textArea。我问的原因是因为使用第二个选项,按钮不在我想要的位置。

【问题讨论】:

"println params?.properties" 在您的控制器中的表单发布中查看为该字段发布的值 @virtualeyes 原谅我,因为我对应用程序的 Web 端还比较陌生,但我看不出您希望我在哪里添加打印语句。 @SG,在 def saveFile 中,但这假设属性文本字段实际上是在 loadFile() 后填充数据。我对 groovy 的了解远胜过我对 grails 的了解——坚持住,这对于全职 grails 用户来说是非常容易实现的目标 等瞧,grails 用户 @jjczopek 来救援 【参考方案1】:

将您的文本字段包装在表单标签中。这样,当您提交它时,您可以访问控制器中的字段。

<g:form controller="myController" action="saveFile">
  <g:textField name="properties"/>
  <g:submitButton name="saveFile" value="Save File" />
</g:form>

然后,您可以访问控制器中的 properties 字段:

def saveFile = 
    def properties = params.properties
    // do whatever you need

编辑:

为了解决后来在 cmets 中出现的一些问题,我将尝试提供更多见解。

假设您的控制器名为Drive,视图(提交属性的表单)为drive/properties.gsp。如果希望您的加载按钮将您的属性加载到文本区域,您可以执行以下操作:

def loadFile = 
   // your code here

   render(view: 'properties.gsp', model=[properties:propList])

在你看来:

<g:form controller="drive">
  <g:textArea name="properties" value="$properties?.join("\n")" rows="50" cols="6"/>
  <br/>
  <g:actionSubmit name="loadFile" action="loadFile" value="Load File"/>
  <g:actionSubmit name="saveFile" action="saveFile" value="Save File"/>
</g:form>

这应该使用文件中的值呈现您的表单,每个属性都在新行中。但我没有测试它。

【讨论】:

这非常适合保存textArea 的内容,现在我只是在从文件中加载它时遇到问题。 谢谢你的例子!我已经用一个附加问题编辑了主要问题,如果你有机会请检查一下 我很欣赏代码,但我认为问题与actionSubmit 相关,即使我添加了您所做的操作属性,这两个按钮似乎也无法找到操作。按下按钮时生成的链接如下所示:drive/list?loadFiledrive/list?saveFile 我不知道为什么它会寻找 list 关于可能发生的任何想法? 它似乎默认 list 作为操作。有没有办法同时包含这两个动作?我认为这是我的问题发生的地方 感谢您的时间和帮助,目前我不会将加载按钮放在其他位置【参考方案2】:

jjczopek's answer 展示了在控制器中的数据从视图提交后如何访问它。

您可以通过在控制器中设置参数来将默认值从控制器传递到视图,例如...

    params.param1 ='value to pass'
    render(view:"testView")

然后在您看来,您可以使用...再次检索它

<g:textField name="text1" value="$params.param1"/>

您可能还会发现this question 和these docs 很有用。

如果想要传递域对象,那么以下特定渲染方法之一可能会更好... Grails Controller - Render

【讨论】:

@Chris 道歉,我有一个 textArea 而不是 textField。我将如何填充textArea?我似乎在通过迭代列表并将值分配给控制器中的参数来将值加载到其中时遇到问题 @Chris 我继续使用getText() 从文件中获取文本,而不是逐行浏览。我还有一个问题,我已经编辑了原文,如果你有机会,请检查一下。也感谢您的帮助,非常感谢! @StartingGroovy,g:submitButton 应该有一个 'action' 参数来指定控制器中的哪个动作要使用grails.org/doc/latest/ref/Tags/actionSubmit.html。例如 action="loadFile" 它默认为 'value' 参数,但你现在有一个空格,这就是我认为它不起作用的原因。 @Chris,你试过添加 action="loadFile" 吗?如果将操作参数添加到 g:submitButton 则值参数将仅用于显示按钮文本 我修改了我的答案,也许有些事情会清楚。我没有测试此代码,因此它可能无法正常工作。

以上是关于Grails - 控制器和视图之间的通信的主要内容,如果未能解决你的问题,请参考以下文章

UISplitViewController 中两个视图控制器之间的通信

如何从 Grails 控制器和视图外部引用 Grails 域类字段?

两个 childViewController 之间的通信

如何创建不同名称的控制器和视图 Grails 脚手架

Grails 渲染不同控制器的视图

如何知道 UIKit 视图控制器中的 swiftUI 事件? ||如何提供 swiftUI 和 uikit 之间的通信