下面我们在范例程序中集成AJAX地图,使应用程序更加可视化。这样,在用户创建、编辑或者查看宴会信息时,可以看到宴会的地理位置信息。
创建Map Partial
视图
我们计划在应用程序中多个地方使用地图功能。为了保持代码的简洁,我们封装通用的地图功能在一个单一的partial视图模板中,然后在多个Controller action方法和视图中重用。对该新建的partial视图命名为map.ascx,创建在\Views\Dinners目录。
如下图所示,创建map.ascx partial视图,并设置传递Dinner模型类作为View Data Class:
进一步更新Map.ascx 文件,代码如下:
<script src="http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2" type="text/javascript"></script>
<script src="/Scripts/Map.js" type="text/javascript"></script>
<div id="theMap">
</div>
<script type="text/javascript">
$(document).ready(function() {
var latitude = <%=Model.Latitude %>;
var longitude = <%=Model.Longitude %>;
if ((latitude == 0) || (longitude == 0))
LoadMap();
else
LoadMap(latitude, longitude, mapLoaded);
});
function mapLoaded() {
var title = "<%= Html.Encode(Model.Title) %>";
var address = "<%= Html.Encode(Model.Address) %>";
LoadPin(center, title, address);
map.SetZoomLevel(14);
}
</script>
第一部分<script>引用指向微软的Virtual Earth 6.2地图库,第二部分<script>引用指向map.js 文件,该文件将封装通用的JavaScript地图逻辑。<div id=”theMap”>元素是一个HTML容器,Virtual Earth将使用该容器来承载地图。
接下来包含了2段嵌入的<script>代码块,视图相关的2个JavaScript功能。第一个函数是当页面准备好运行客户端脚本时,使用jQuery调用一个函数。它调用LoadMap() 辅助函数,该函数定义在Map.js脚本文件中,用来加载virtual earth 地图控件。第二个是一个回调事件句柄,添加一个别针在地图上,标识位置。
你会注意到我们在客户端脚本中使用服务端的<%= %>代码块,嵌入Dinner的经度和维度属性。这一技术非常有用,可以输出动态值在客户端脚本中使用(不需要一个单独的AJAX回调到服务端去检索值 – 使得响应更快)。<%= %>代码块在视图在Server端呈现时将执行,因此,HTML输出将嵌入的JavaScript 值(如,var latitude = 47.64312)。
创建一个Map.js
工具类库
开始创建Map.js文件,用来封装地图的JavaScript功能,并实现上述的LoadMap和LoadPin方法。右键点击项目中的\Scripts目录,并选择 Add -> New Item 菜单项,选择JScript 项目,命名为Map.js。
下面是添加到Map.js文件中的JavaScript代码,该代码复制和Virtual Earth交互,并显示地图和Dinner对象的位置标识:
具体JavaScript代码 – 请参考原文149页,这里不重复了。
集成地图到创建和编辑表单
我们将集成地图到现有的创建和编辑视图。这点比较容易做到,不需要更改任何Controller代码。因为创建和编辑视图共享一个通用的DinnerForm partial视图,展示Dinner的用户界面,因为我们只需要在一个地方添加地图,就可以在创建和编辑视图中看到了。
我们需要做的是,打开\Views\Dinners\DinnerForm.ascx partial 视图,并更新它包含新的map partial视图。如下是更新后的DinnerForm视图的代码(注:为了代码的简洁性,这里忽略了HTML 表单的元素):
<div id="mapDiv">
<% Html.RenderPartial("Map", Model.Dinner); %>
</div>
DinnerForm partial 视图接收类型为DinnerFormViewModel作为模型类型(因为它既需要一个Dinner对象,也需要一个SelectList填充国家下拉列表框)。Map partial 视图仅仅需要类型为Dinner的模型类型,因此当我们呈现Map partial视图时,我们传递DinnerFormViewModel.Dinner属性给它。
关于NerdDinner范例程序和Map地图集成的内容,因为涉及过多JavaScript的内容,本人对此不甚了解,也没有什么兴趣,就忽略了(原文内容从152页-165页)。