首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

Grails 服务和 Google 地图(2)

Grails 服务和 Google 地图(2)

加入服务首先,把新的 lat 和 lng 字段添加到 grails-app/domain/Airport.groovy,如清单 6 所示:
清单 6. 把 lat 和 lng 字段添加到 Airport POGO
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Airport{
  static constraints = {
    name()
    iata(maxSize:3)
    city()
    state(maxSize:2)
    country()
  }
   
  String name
  String iata
  String city
  String state
  String country = "US"
  String lat
  String lng
   
  String toString(){
    "${iata} - ${name}"
  }
}




在命令提示处输入 grails generate-views Airport 来创建 GSP 文件。借助 AirportController.groovy 的 def scaffold = Airport 行,从运行时开始就一直在动态搭建 GSP 文件。要想对这个视图进行更改,我必须先处理代码。
创建新的 Airport 时,我将把用户可编辑字段限制为 iata 和 city。要想让地理编码查询能够工作,必须具备 iata 字段。我没有更改 city,因为我喜欢由自己来提供这个信息。DEN 真的就在丹佛(Denver),但 ORD(Chicago O'Hare)却在伊里诺斯州的罗斯蒙特(Rosemont),而 CVG(俄亥俄州辛辛那提机场,Cincinnati,Ohio airport)则在肯塔基州的佛罗伦萨市(Florence)。将这两个字段留在 create.gsp 里,其余的删除。现在 create.gsp 如清单 7 所示:
清单 7. 修改 create.gsp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<g:form action="save" method="post" >
  <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>                                                
      </tbody>
    </table>
  </div>
  <div class="buttons">
    <span class="button"><input class="save" type="submit" value="Create" /></span>
  </div>
</g:form>




图 2 展示了所产生的表单:
图 2. 创建 Airport 表单该表提交到 AirportController 中的 save 闭包。将清单 8 中的代码添加到控制器,以在保存新的 Airport 之前调用 geocodeAirport:
清单 8. 修改 save 闭包
1
2
3
4
5
6
7
8
9
10
11
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。第二行将 resultsHashMap 和 paramsHashMap 合并起来(当然,在 Groovy 中合并两个 HashMap 就像把它们添加到一起一样简单)。
如果数据库保存成功的话,将重定向到显示操作。幸运的是,不需要更改 show.gsp,如图 3 所示:
图 3. 显示 Airport 表单要编辑 Airport,必须保持 iata 和 city 字段在 edit.gsp 中不变。您可以从 show.gsp 复制和粘贴其余的字段,把它们变为只读字段(或者,如果您能从 前期文章 体会到 “复制和粘贴是面向对象编程的最低级形式” 的话,您可以把常用字段提取到一个局部模板并在 show.gsp 和 edit.gsp 中呈现它)。清单 9 展示了修改后的 edit.gsp:
清单 9. 修改 edit.gsp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<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>

返回列表