понедельник, 20 июня 2011 г.

MVC - часть1. Загрузка данных


Итак, у нас те же исходные данные, что и раньше. Но приложение будем строить ASP.Net MVC 3 Web Application. Студия предложит выбрать шаблон приложения, я выбираю Internet Application и движок Razor (позднее обсудим, почему именно так стоит делать). Теперь у нас есть заготовка нашего проекта. В этой заготовке есть лишние элементы (они особо не помешают, но и место занимать ни к чему), поэтому я удаляю: контроллер AccountController.cs, модель AccountModels.cs, удаляю папку Account во View, а также файлы _LogOnPartial.cshtml и Error.cshtml. Этого будет достаточно для начала работы. При запуске проекта студия поругается на файл _Layout.cshtml на строку:
            <div id="logindisplay">
                @Html.Partial("_LogOnPartial")
            </div>
это произошло из-за того, что представление, на которое тут идет ссылка, мы удалили. Заменим ссылку на тег <br />. Запустим снова проект – все работает.
Для начала создадим саму карту. Открываем Index.cshtml и убираем все кроме верхних трех строк. Ниже вставляем известный по прошлым статьям код (листинг 1).
Листинг 1 – Загрузка карты
    <script src="http://api-maps.yandex.ru/1.1/index.xml?key=”тут ваш ключ
        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);
        });

    </script>

    <div id="YMapsID" style="width: 100%; height: 600px; padding-left: 0px; ">
    </div>

Запускаем проект и видим пустую карту. Это готово, хорошо. Теперь нам нужны данные на этой карте. В самой первой статье для загрузки мы пользовались HttpHandler’ом. В архитектуре MVC им пользоваться не с руки по архитектурным соображениям, поэтому попробуем загрузить данные в методе контроллера. Для этого откроем наш HomeController и добавим ему метод, как в листинге 2.
Листинг 2 – Получение данных
        [AcceptVerbs(HttpVerbs.Get)]
        public JsonResult ObjectToMap()
        {
            List<object> list = new List<object>();

            string connString = ConfigurationManager.ConnectionStrings["project"].ConnectionString;
            using (SqlConnection con = new SqlConnection(connString))
            {
                string sql = "exec dbo.p_Get_MyObject_Info ";

                SqlCommand cmd = new SqlCommand(sql, con);
                con.Open();
                using (SqlDataReader reader = cmd.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        var data = new
                        {
                            Name = reader.GetString(0),
                            Latitude = reader.GetString(2),  //широта
                            Longitude = reader.GetString(1), //долгота
                        };
                        list.Add(data);
                    }
                }
                con.Close();
            }
           
            return Json(list, JsonRequestBehavior.AllowGet);
        }

Как видно из этого листинга, код почти идентичен коду HttpHandler'а. Есть одно отличие – перед телом метода указан атрибут [AcceptVerbs(HttpVerbs.Get)]. Он отвечает за то, что метод будет обрабатывать http-запрос Get, в то время как Post у нас пока не реализован. Не забудьте в Web.Config добавить строку соединения project и реализовать процедуру, формирующую данные для карты dbo.p_Get_MyObject_Info. Хорошо. Теперь мы должны получить данные на стороне клиента и отобразить их.
Для этого в представлении Index к jQuery коду добавим функцию из листинга 3.
Листинг 3 – Получение данных на клиенте
            function getObject() {
            $.getJSON("/Home/ObjectToMap", null, function (mapObj) {
                // Группа объектов
                group["new"] = new YMaps.GeoObjectCollection("default#");

                $.each(mapObj, function (i) {
                    var point = new YMaps.GeoPoint(this.Longitude, this.Latitude);
                    var placemark = new YMaps.Placemark(point);
                    placemark.name = this.Name;

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

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

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

Тут мы обращаемся к методу контроллера, который реализовали раньше и в цикле грузим данные на карту. И, наконец, нужно вызвать эту функцию в конце функции $(document).ready. Запускаем проект и видим, что на карте отображны наши объекты.
Победа? Как бы не так! Оказывается, получение данных в контроллере не есть методологически верное решение. Исправлять ситуацию будем в следующей статье.
И, как всегда, принимаются пожелания, указания на недочеты и ошибки, вопросы.

Комментариев нет: