プロジェクト (MVC3 および Razor エンジン) に Bing マップをアップロードしたいと考えています。夕食を処理し、bing マップを表示するためのビューの作成と編集があります。問題は、編集ビューのみがマップを表示でき、作成ビューは表示できないことです。ただし、どちらのビューも「DinnerForm」と呼ばれる同じ部分ビューをレンダリングします。なぜこの問題が発生するのか疑問に思っています。
作成ビュー
@model NerdDinner.Models.DinnerFormViewModel
@{
ViewBag.Title = "Create";
}
<h2>Host a dinner</h2>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
@{Html.RenderPartial("DinnerForm");}
編集ビュー
@model NerdDinner.Models.DinnerFormViewModel
ViewBag.Title = @Html.Encode(Model.Dinner.Title);
<h2>Edit</h2>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
@{Html.RenderPartial("DinnerForm");}
DinnerForm ビュー
@model NerdDinner.Models.DinnerFormViewModel
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<div class="editor-label">
@Html.LabelFor(model => model.Dinner.Title)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Dinner.Title)
@Html.ValidationMessageFor(model => model.Dinner.Title)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Dinner.Latitude)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Dinner.Latitude)
@Html.ValidationMessageFor(model => model.Dinner.Latitude)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Dinner.Longitude)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Dinner.Longitude)
@Html.ValidationMessageFor(model => model.Dinner.Longitude)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Dinner.EventDate)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Dinner.EventDate)
@Html.ValidationMessageFor(model => model.Dinner.EventDate)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Dinner.ContactPhone)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Dinner.ContactPhone)
@Html.ValidationMessageFor(model => model.Dinner.ContactPhone)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Dinner.Address)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Dinner.Address)
@Html.ValidationMessageFor(model => model.Dinner.Address)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Dinner.Country)
</div>
<div class="editor-field">
@Html.DropDownList("Country", @Model.Countries)
@Html.ValidationMessageFor(model => model.Countries)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Dinner.HostedBy)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Dinner.HostedBy)
@Html.ValidationMessageFor(model => model.Dinner.HostedBy)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Dinner.Description)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Dinner.Description)
@Html.ValidationMessageFor(model => model.Dinner.Description)
</div>
<p>
<input type="submit" value="Save" />
</p>
<div id="mapDiv">
@{Html.RenderPartial("Map", Model.Dinner);}
</div>
</fieldset>
<script type="text/javascript">
$(document).ready(function () {
$("#Address").blur(function (evt) {
$("#Latitude").val("");
$("#Longitude").val("");
var address = jQuery.trim($("#Address").val());
if (address.length < 1)
return;
FindAddressOnMap(address);
});
});
</script>
}
マップビューは編集のページに表示されるので問題ありません。
map 関数にアクセスするために NerdDinner という js ファイルがあります。そこに FindAddressOnMap() 関数が定義されています。
function NerdDinner() { }
NerdDinner.MapDivId = 'theMap';
NerdDinner._map = null;
NerdDinner._points = [];
NerdDinner._shapes = [];
NerdDinner.LoadMap = function (latitude, longitude, onMapLoaded) {
NerdDinner._map = new VEMap(NerdDinner.MapDivId);
var options = new VEMapOptions();
options.EnableBirdseye = false
// Makes the control bar less obtrusize.
this._map.SetDashboardSize(VEDashboardSize.Small);
if (onMapLoaded != null)
NerdDinner._map.onLoadMap = onMapLoaded;
if (latitude != null && longitude != null) {
var center = new VELatLong(latitude, longitude);
}
NerdDinner._map.LoadMap(center, null, null, null, null, null, null, options);
}
NerdDinner.ClearMap = function () {
NerdDinner._map.Clear();
NerdDinner._points = [];
NerdDinner._shapes = [];
}
NerdDinner.LoadPin = function (LL, name, description) {
var shape = new VEShape(VEShapeType.Pushpin, LL);
//Make a nice Pushpin shape with a title and description
shape.SetTitle("<span class=\"pinTitle\"> " + escape(name) + "</span>");
if (description !== undefined) {
shape.SetDescription("<p class=\"pinDetails\">" + escape(description) + "</p>");
}
NerdDinner._map.AddShape(shape);
NerdDinner._points.push(LL);
NerdDinner._shapes.push(shape);
}
NerdDinner.FindAddressOnMap = function (where) {
var numberOfResults = 1;
var setBestMapView = true;
var showResults = true;
var defaultDisambiguation = true;
NerdDinner._map.Find("", where, null, null, null,
numberOfResults, showResults, true, defaultDisambiguation,
setBestMapView, NerdDinner._callbackForLocation);
}
NerdDinner._callbackForLocation = function (layer, resultsArray, places, hasMore, VEErrorMessage) {
NerdDinner.ClearMap();
if (places == null) {
NerdDinner._map.ShowMessage(VEErrorMessage);
return;
}
//Make a pushpin for each place we find
$.each(places, function (i, item) {
var description = "";
if (item.Description !== undefined) {
description = item.Description;
}
var LL = new VELatLong(item.LatLong.Latitude,
item.LatLong.Longitude);
NerdDinner.LoadPin(LL, item.Name, description);
});
//Make sure all pushpins are visible
if (NerdDinner._points.length > 1) {
NerdDinner._map.SetMapView(NerdDinner._points);
}
//If we've found exactly one place, that's our address.
//lat/long precision was getting lost here with toLocaleString, changed to toString
if (NerdDinner._points.length === 1) {
$("#Latitude").val(NerdDinner._points[0].Latitude.toString());
$("#Longitude").val(NerdDinner._points[0].Longitude.toString());
}
}
NerdDinner.FindDinnersGivenLocation = function (where) {
NerdDinner._map.Find("", where, null, null, null, null, null, false,
null, null, NerdDinner._callbackUpdateMapDinners);
}
NerdDinner.FindMostPopularDinners = function (limit) {
$.post("/Search/GetMostPopularDinners", { "limit": limit }, NerdDinner._renderDinners, "json");
}
NerdDinner._callbackUpdateMapDinners = function (layer, resultsArray, places, hasMore, VEErrorMessage) {
var center = NerdDinner._map.GetCenter();
$.post("/Search/SearchByLocation",
{ latitude: center.Latitude, longitude: center.Longitude },
NerdDinner._renderDinners,
"json");
}
NerdDinner._renderDinners = function (dinners) {
$("#dinnerList").empty();
NerdDinner.ClearMap();
$.each(dinners, function (i, dinner) {
var LL = new VELatLong(dinner.Latitude, dinner.Longitude, 0, null);
// Add Pin to Map
NerdDinner.LoadPin(LL, _getDinnerLinkHTML(dinner), _getDinnerDescriptionHTML(dinner));
//Add a dinner to the <ul> dinnerList on the right
$('#dinnerList').append($('<li/>')
.attr("class", "dinnerItem")
.append(_getDinnerLinkHTML(dinner))
.append($('<br/>'))
.append(_getDinnerDate(dinner, "mmm d"))
.append(" with " + _getRSVPMessage(dinner.RSVPCount)));
});
// Adjust zoom to display all the pins we just added.
if (NerdDinner._points.length > 1) {
NerdDinner._map.SetMapView(NerdDinner._points);
}
// Display the event's pin-bubble on hover.
$(".dinnerItem").each(function (i, dinner) {
$(dinner).hover(
function () { NerdDinner._map.ShowInfoBox(NerdDinner._shapes[i]); },
function () { NerdDinner._map.HideInfoBox(NerdDinner._shapes[i]); }
);
});
function _getDinnerDate(dinner, formatStr) {
return '<strong>' + _dateDeserialize(dinner.EventDate).format(formatStr) + '</strong>';
}
function _getDinnerLinkHTML(dinner) {
return '<a href="' + dinner.Url + '">' + dinner.Title + '</a>';
}
function _getDinnerDescriptionHTML(dinner) {
return '<p>' + _getDinnerDate(dinner, "mmmm d, yyyy") + '</p><p>' + dinner.Description + '</p>' + _getRSVPMessage(dinner.RSVPCount);
}
function _dateDeserialize(dateStr) {
return eval('new' + dateStr.replace(/\//g, ' '));
}
function _getRSVPMessage(RSVPCount) {
var rsvpMessage = "" + RSVPCount + " RSVP";
if (RSVPCount > 1)
rsvpMessage += "s";
return rsvpMessage;
}
}
NerdDinner.dragShape = null;
NerdDinner.dragPixel = null;
NerdDinner.EnableMapMouseClickCallback = function () {
NerdDinner._map.AttachEvent("onmousedown", NerdDinner.onMouseDown);
NerdDinner._map.AttachEvent("onmouseup", NerdDinner.onMouseUp);
NerdDinner._map.AttachEvent("onmousemove", NerdDinner.onMouseMove);
}
NerdDinner.onMouseDown = function (e) {
if (e.elementID != null) {
NerdDinner.dragShape = NerdDinner._map.GetShapeByID(e.elementID);
return true;
}
}
NerdDinner.onMouseUp = function (e) {
if (NerdDinner.dragShape != null) {
var x = e.mapX;
var y = e.mapY;
NerdDinner.dragPixel = new VEPixel(x, y);
var LatLong = NerdDinner._map.PixelToLatLong(NerdDinner.dragPixel);
$("#Latitude").val(LatLong.Latitude.toString());
$("#Longitude").val(LatLong.Longitude.toString());
NerdDinner.dragShape = null;
NerdDinner._map.FindLocations(LatLong, NerdDinner.getLocationResults);
}
}
NerdDinner.onMouseMove = function (e) {
if (NerdDinner.dragShape != null) {
var x = e.mapX;
var y = e.mapY;
NerdDinner.dragPixel = new VEPixel(x, y);
var LatLong = NerdDinner._map.PixelToLatLong(NerdDinner.dragPixel);
NerdDinner.dragShape.SetPoints(LatLong);
return true;
}
}
NerdDinner.getLocationResults = function (locations) {
if (locations) {
var currentAddress = $("#Dinner_Address").val();
if (locations[0].Name != currentAddress) {
var answer = confirm("Bing Maps returned the address '" + locations[0].Name + "' for the pin location. Click 'OK' to use this address for the event, or 'Cancel' to use the current address of '" + currentAddress + "'");
if (answer) {
$("#Dinner_Address").val(locations[0].Name);
}
}
}
}