четверг, 28 июля 2011 г.

MVC - часть3. CRUD логика (Detail)


Итак, в прошлой статье мы получили список объектов карты. Возле каждого объекта у нас имеется ссылки, в том числе и «Details». Вот о ней и поговорим. Сама по себе страница с подробностями об объекте не так интересна, но у нас же карта, так давайте вместе с подробностями отобразим небольшую карту, где бы отображался этот самый объект.
Сперва пишем экшен контроллера (листинг 1), а затем генерируем представление (листинг 2).
Листинг 1Экшен контроллера
        [HttpGet]
        public ActionResult MapObject_Details(long id)
        {
            if (id != 0)
            {
                DataManager db = new DataManager();

                return View(db.GetMapObject(id));
            }
            else
            {
                return View();
            }
        }
Листинг 2Представление Details
<fieldset>
    <legend>Map</legend>

    <div class="display-label">ObjName</div>
    <div class="display-field">
        @Html.DisplayFor(model => model.ObjName)
    </div>

    <div class="display-label">ObjAddress</div>
    <div class="display-field">
        @Html.DisplayFor(model => model.ObjAddress)
    </div>

    <div class="display-label">ObjType</div>
    <div class="display-field">
        @Html.DisplayFor(model => model.ObjType_id)
    </div>

    <div class="display-label">Description</div>
    <div class="display-field">
        @Html.DisplayFor(model => model.Description)
    </div>

    <div class="display-label">Contact</div>
    <div class="display-field">
        @Html.DisplayFor(model => model.Contact)
    </div>

    <div class="display-label">Longitude</div>
    <div class="display-field">
        @Html.DisplayFor(model => model.Longitude)
    </div>

    <div class="display-label">Latitude</div>
    <div class="display-field">
        @Html.DisplayFor(model => model.Latitude)
    </div>

    <div class="display-label">ObjType_id</div>
    <div class="display-field">
        @Html.DisplayFor(model => model.ObjType_id)
    </div>

    <div class="display-label">Author</div>
    <div class="display-field">
        @Html.DisplayFor(model => model.Author)
    </div>

    <div class="display-label">CreateDate</div>
    <div class="display-field">
        @Html.DisplayFor(model => model.CreateDate)
    </div>
</fieldset>

Дополним эту разметку еще одним полем – скрытым:
@Html.HiddenFor(model => model.MapObj_id)

В этом скрытом поле на нашей странице будет присутствовать идентификатор объекта. Зачем он нам? А мы по его значению будем на карту грузить его балун. Рассмотрим, как. Для начала сделаем метод нашего менеджера данных, который по идентификатору будет отдавать данные об объекте (листинг 3).
Листинг 3 – Получаем данные объекта по идентификатору
        public List<object> GetMapObjectById(long mapObjId)
        {
            List<object> list = new List<object>();

            Map item = GetMapObject(mapObjId);

            var data = new
            {
                Name = item.ObjName,
                Style = item.MapObjType.Style,
                Latitude = item.Latitude,  //широта
                Longitude = item.Longitude, //долгота
                Html = "<table class='info'>" +
                        "<tr><th>Название</th><td>" + item.ObjName + "</td></tr>" +
                        "<tr><th>Адрес</th><td>" + item.ObjAddress + "</td></tr>" +
                        "<tr><th>Описание</th><td>" + item.Description + "</td></tr>" +
                        "<tr><th>Контакты</th><td>" + item.Contact + "</td></tr>" +
                        "<tr><th>Оценка</th><td>" + ((item.MiddleRating != 0) ? item.MiddleRating.ToString() : "нет") + "</td></tr>" +
                        "<tr><th><a href='/Home/Comment/" + item.MapObj_id + "'>Отзывы</a></th><td></td></tr>" +
                        "</table>",      //код для балуна
            };

            list.Add(data);

            return list;
        }

Как видно, тут мы формируем код балуна, который позже загрузим в js-скрипте.
Теперь пишем экшен, который запакует это все дело в JSON (листинг 4).
Листинг 4 – Экшен, передающий данные в представление
        [HttpGet]
        public JsonResult ObjectDetails(long mapObjId)
        {
            DataManager db = new DataManager();

            return Json(db.GetMapObjectById(mapObjId), JsonRequestBehavior.AllowGet);
        }

Остался скрипт, который загрузит наш JSON на карту (листинг 5).
Листинг 5 – Скрипт отображения данных на карте
<script src="http://api-maps.yandex.ru/1.1/index.xml?key=AAFDuU0BAAAAWmDlWgMAn8sg2dtfRwaCuNPYn0etp5qnk6QAAAAAAAAAAAAwqKOA3GzAs8EObkeouS3eI9xZMA=="
        type="text/javascript">
    </script>

    <script type="text/javascript" src="../../Scripts/jquery-1.5.1.min.js">
    </script>

    <script type="text/javascript" >
        var group = [];
        var map;

        $(document).ready(function () {
            // Найдем на странице html элемент в котором будет размещаться карта
            map = new YMaps.Map(YMaps.jQuery("#YMapsID")[0]);

            map.setCenter(new YMaps.GeoPoint(55.975669, 54.732613), 10);

            // добавим контролы
            map.addControl(new YMaps.ToolBar());
            map.addControl(new YMaps.Zoom());
            map.addControl(new YMaps.TypeControl());
            map.enableScrollZoom();

            var searchControl = new YMaps.SearchControl({
                resultsPerPage: 2,  // Количество объектов на странице
                useMapBounds: 1     // Объекты, найденные в видимой области карты
                // будут показаны в начале списка
            });
            map.addControl(searchControl);

            getObject(document.getElementById('MapObj_id').value);
        });

        // объект по идентификатору
        function getObject(mapObjId) {

            $.getJSON("/Home/ObjectDetails", { mapObjId: mapObjId }, function (mapObj) {

                var s;

                group["new"] = new YMaps.GeoObjectCollection("default#");

                $.each(mapObj, function (i) {

                    // Создание стиля для значка метки
                    s = new YMaps.Style();
                    s.iconStyle = new YMaps.IconStyle();
                    s.iconStyle.href = this.Style;
                    s.iconStyle.size = new YMaps.Point(18, 18);
                    s.iconStyle.offset = new YMaps.Point(-9, -9);
                    s.balloonContentStyle = new YMaps.BalloonContentStyle(
                            new YMaps.Template("<div>$[description]</div>")
                    );

                    var point = new YMaps.GeoPoint(this.Longitude, this.Latitude);
                    var placemark = new YMaps.Placemark(point, { hasHint: 1, style: s });
                    placemark.name = this.Name;

                    //тут засовываем html
                    placemark.description = this.Html + "<br />";

                    group["new"].add(placemark);
                });

                map.addOverlay(group["new"]);
            });
        };

    </script>

В общем то, схема уже нам знакома, комментировать нечего.
Результат на рисунке 1.

Рисунок 1 – Подробности об объекте карты


6 комментариев:

Сергей комментирует...

Спасибо. Сейчас буду учиться.....

George комментирует...

С удовольствием читаю вашу серию уроков. Не забрасывайте это дело, людям нужна ваша работа.
Успехов вам! Еще раз спасибо :)

dedMazDie комментирует...

Спасибо!
Буду стараться :)
Есть очередная статья, но я ее попробовал на http://habrahabr.ru/ опубликовать. Там она сейчас в песочнице. Вдруг тоже кто то проголосует, было бы здорово. Хотя это не уровень хабра конечно :))

Сергей комментирует...

Нашел статью на хабре. Проголосовать не могу, недостаточно кармы.

Сергей комментирует...

Вот и я тоже сделал у себя на сайте отображение карты при детальном просмотре. Спасибо.

dedMazDie комментирует...

Всегда пожалуйста! :)