如何在Grails

时间:2015-04-24 17:28:34

标签: grails data-binding

我正在尝试通过向DB添加实体来执行标准流程。流程应如下所示:

  1. 用户打开链接 example.co/connection/putForm
  2. 编辑所有字段
  3. 提交(POST)到 example.co/connection/put
  4. 如果没有错误,那么他被重定向到 ../ conncetion / index ,否则他应该看到填写了所有字段的前一个表单(步骤2)和错误消息
  5. 现在我的代码看起来像这样:

    def putForm() {
        [
                providers: Provider.findAll(),
                cities   : City.findAll()
        ]
    }
    
    @Transactional
    def put() {
        // not important part of parsing fields from params
        def provider = Provider.get(params.provider)
        def startTime = parseStartTime(params)
        def path = parsePath(params)
        def departurePlace = params.departurePlace
    
        def connection = new Connection(provider: provider, startTime: startTime, departurePlace: departurePlace, path: path)
        if (connection.save()) {
            redirect controller: 'connection', action: 'index', params: [addedConnection: connection.id] // this part is OK
        } else {
            render view: 'putForm', params: params, model: [connection: connection] // this sucks... look below
        }
    }
    

    问题是我需要渲染视图 putForm ,但是来自链接 ... / connection / put 。这导致在此渲染之后所有文本字段都为空的问题(上面的步骤4)。我也有丑陋的链接。

    Grails有这种常见情况的模式吗?

    PS我不能使用脚手架。

1 个答案:

答案 0 :(得分:1)

You're not that far off.. try this:

def putForm() {
    [
            providers: Provider.findAll(),
            cities   : City.findAll(),
connection: new Connection()  // everything defaulted to empty or whatever you want the default to be
    ]
}

@Transactional
def put( Connection connection ) {
    // NOTE: by putting the connection as the parameter to this action,
    // all params.X that match a property X in the connection will auto-
    // populate, even the Provider, assuming the value of params.provider.id
    // is the id of a provider or blank (in which case 
    // connection.provider will be null.

    // Skip this now
    //def provider = Provider.get(params.provider)
    //def startTime = parseStartTime(params)
    //def path = parsePath(params)
    //def departurePlace = params.departurePlace
    //def connection = new Connection(provider: provider, 
    // startTime: startTime, departurePlace: departurePlace, path: path)

    if (connection.save()) {
        redirect controller: 'connection', action: 'index', 
           params: [addedConnection: connection.id] // this part is OK
    } else {
        render view: 'putForm', model: [
            providers: Provider.findAll(),
            cities   : City.findAll(),
            connection: connection] 
    }
}

The thing you need now is to make sure your putForm.gsp actually uses the values you sent down. You should put in things like:

<g:input name="path" type="text" 
         value="${fieldValue( bean:connection, field:'path' )}" />

and

<g:select name="provider.id" from="${providers}"   // note the .id in places here
          value="${connection.provider?.id ?: ''}"
          noSelection="['':'None']"/>

Note that these will populate with whatever is in the connection sent down each time the page is rendered. So the first time it'll just have the default values, and if it has to rerender due to errors, it'll have the connection values that failed validation.

Hope this helps.