技术开发 频道

精通 Grails: Grails 服务和 Google 地图

  该表提交到 AirportController 中的 save 闭包。将清单 8 中的代码添加到控制器,以在保存新的 Airport 之前调用 geocodeAirport:

  清单 8. 修改 save 闭包

                def save = {
    def results
= geocoderService.geocodeAirport(params.iata)    
    def airport
= new Airport(params + results)
    
if(!airport.hasErrors() && airport.save()) {
        flash.message
= "Airport ${airport.id} created"
        redirect(action:show,id:airport.id)
    }
    
else {
        render(view:
'create',model:[airport:airport])
    }
}

  如果在命令提示处输入 grails generate-controller Airport,方法的主要部分将与您所看到的一样。仅仅是开始的两行与默认生成的闭包不同。第一行从 geocoder 服务获得一个 HashMap。第二行将 results HashMap 和 params HashMap 合并起来(当然,在 Groovy 中合并两个 HashMap 就像把它们添加到一起一样简单)。

  如果数据库保存成功的话,将重定向到显示操作。幸运的是,不需要更改 show.gsp,如图 3 所示:

  图 3. 显示 Airport 表单  

  要编辑 Airport,必须保持 iata 和 city 字段在 edit.gsp 中不变。您可以从 show.gsp 复制和粘贴其余的字段,把它们变为只读字段(或者,如果您能从 前期文章 体会到 “复制和粘贴是面向对象编程的最低级形式” 的话,您可以把常用字段提取到一个局部模板并在 show.gsp 和 edit.gsp 中呈现它)。清单 9 展示了修改后的 edit.gsp:

  清单 9. 修改 edit.gsp

<g:form method="post" >
  
<input type="hidden" name="id" value="${airport?.id}" />
  
<div class="dialog">
    
<table>
      
<tbody>                                              
        
<tr class="prop">
          
<td valign="top" class="name"><label for="iata">Iata:</label></td>
          
<td valign="top"
              class
="value ${hasErrors(bean:airport,field:'iata','errors')}">
              
<input type="text"
                     maxlength
="3"
                     id
="iata"
                     name
="iata"
                     value
="${fieldValue(bean:airport,field:'iata')}"/>
          
</td>
        
</tr>                        
        
<tr class="prop">
          
<td valign="top" class="name"><label for="city">City:</label></td>
          
<td valign="top"
              class
="value ${hasErrors(bean:airport,field:'city','errors')}">
              
<input type="text"
                     id
="city"
                     name
="city"
                     value
="${fieldValue(bean:airport,field:'city')}"/>
          
</td>
        
</tr>
        
<tr class="prop">
          
<td valign="top" class="name">Name:</td>
          
<td valign="top" class="value">${airport.name}</td>
        
</tr>
        
<tr class="prop">
          
<td valign="top" class="name">State:</td>
          
<td valign="top" class="value">${airport.state}</td>
        
</tr>
        
<tr class="prop">
          
<td valign="top" class="name">Country:</td>
          
<td valign="top" class="value">${airport.country}</td>
        
</tr>
        
<tr class="prop">
          
<td valign="top" class="name">Lat:</td>
          
<td valign="top" class="value">${airport.lat}</td>
        
</tr>
        
<tr class="prop">
          
<td valign="top" class="name">Lng:</td>
          
<td valign="top" class="value">${airport.lng}</td>
        
</tr>
      
</tbody>
    
</table>
  
</div>
  
<div class="buttons">
    
<span class="button"><g:actionSubmit class="save" value="Update" /></span>
    
<span class="button">
      
<g:actionSubmit class="delete"
                      onclick
="return confirm('Are you sure?');"
                      value
="Delete" />
    
</span>
  
</div>
</g:form>

  所产生的表单如图 4 所示:

  图 4. 编辑 Airport 表单  

  单击 Update 按钮将表单值发送到 update 闭包。将服务调用和 hashmap 合并添加到默认代码,如清单 10 所示:

  清单 10. 修改 update 闭包

def update = {
    def airport
= Airport.get( params.id )
    
if(airport) {
        def results
= geocoderService.geocodeAirport(params.iata)    
        airport.properties
= params + results
        
if(!airport.hasErrors() && airport.save()) {
            flash.message
= "Airport ${params.id} updated"
            redirect(action:show,id:airport.id)
        }
        
else {
            render(view:
'edit',model:[airport:airport])
        }
    }
    
else {
        flash.message
= "Airport not found with id ${params.id}"
        redirect(action:edit,id:params.id)
    }
}

  到目前为止,您已经像 Google Map 一样无缝地将地理编码集成到您的应用程序里。花点时间想一想在应用程序中捕获地址的所有位置 — 顾客、雇员、远程办公室、仓库和零售点等等。通过简单地添加几个字段以存储纬度/经度坐标和加入一个地理编码服务,就能够设置一些简易的地图来显示对象 — 这正是我下一步的工作。

0
相关文章