====== Механизм Values ====== В QP7.Framework для передачи данных между объектами можно использовать //механизм Values//. //Values// - это [[api:qpage#Values|коллекция уровня страницы]]. Срок жизни коллекции //Values// -- текущий запрос. То есть она не сохраняется в сессии и не передается между запросами. Данные в коллекцию //Values// попадают из трех основных источников: *[[http://msdn.microsoft.com/en-us/library/system.web.httprequest.querystring.aspx|HttpRequest.QueryString]] (для ASP -- [[http://msdn.microsoft.com/en-us/library/ms524784.aspx|Request.QueryString]]) *[[http://msdn.microsoft.com/en-us/library/system.web.httprequest.form.aspx|HttpRequest.Form]] (для ASP -- [[http://msdn.microsoft.com/en-us/library/ms525985.aspx|Request.Form]]) *Вызов функции [[api:qpage:values#AddValue]] из пользовательского кода Идея передачи данных между объектами через коллекцию Values хорошо ложится в русло технологии ASP, так как в ней применяется прямое исполнения кода (как написано). В случае же ASP.NET из-за событийно-ориентированного подхода есть ряд ограничений использования этого механизма. ==== Передача данных от родительского объекта к дочернему==== Рассмотрим дерево контролов некоторой страницы ASP.NET. При статической загрузке контролов событие //Init// распространяется в обратном порядке (от листьев к корню), поэтому передача данных в этом случае невозможна. Поэтому QP7.Framework использует динамическую загрузку вместе с собственной последовательностью событий //Init//. Стоит отметить что при загрузке объекта через Presentation, используется контрол //qp:placeholder//, и он вроде бы должен загружаться статически, но фактически он представляет собой оболочку, которая в свою очередь динамически загружает нужный контрол. Так как сама оболочка загружается статически, то передача данных из родительского объекта в дочерний, который вызван через //qp:placeholder// невозможна. У данной реализации есть один непрятный побочный эффект: из-за использования собственной последовательности событий //Init// перестает правильно работать назначение контролам клиентских ID, а следовательно потом страница не может корректно восстановить Viewstate. Это приводит к тому, что при использовании серверных контролов внутри контролов QP7 первые могут сохранить свое состояние. Решение этой проблемы -- заключение такого контрола или группы контролов в отдельный объект шаблона (страницы), который должен быть вызван одним из следующих способов: * * ShowObjectSimple("News", this); то есть с использованием атрибута //simple = true// для //qp:placeholder// или с помощью метода [[api:qpage:objects|ShowObjectSimple]]. При этом передача данных в такой объект работать не будет. ==== Передача данных от родительского объекта к дочернему==== Возможна при тех же ограничениях, что и в предыдущем случае. При этом надо внимательно следить за тем, чтобы значения не использовались раньше, чем были получены. ==== Передача данных между итерациями Publishing Container ==== Если для вывода информации Publishing Container используется сгенерированный по умолчанию [[http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.repeater.aspx|Repeater]], то записывать значение для следующей итерации в Value лучше всего в обработчике события [[http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.repeater.onitemdatabound.aspx|OnItemDataBound]], а использовать в логике для формирования текущего вывода - в обработчике события [[http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.repeater.onitemcreated.aspx|OnItemCreated]]. ==== Использование Values ==== При использовании //Values// в качестве составных частей фильтров //Publishing Container// рекомендуется использовать либо функцию [[api:qpage:values#NumValue]], либо функцию [[api:qpage:values#StrValue]]. Первая подходит для числовых параметров: если на ее входе не число, то она возвращает 0, тем самым гарантируя числовой результат. Вторая функция хорошо подходит для строковых параметров: она удваивает апострофы, в отличие от функции [[api:qpage:values#Value]], которая их удаляет. Рекомендованные способы применения этих функций в фильтрах: "[content_item_id] = " + NumValue("id") "[Name] = '" + StrValue("name") + "'" Аккуратная работа с апострофами необходима, чтобы избежать возможности [[http://ru.wikipedia.org/wiki/%D0%92%D0%BD%D0%B5%D0%B4%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_SQL-%D0%BA%D0%BE%D0%B4%D0%B0|SQL-инъекции]]. Если нужно получить значение из коллекции Values в неизменном виде (без удалений и замен апострофов, преобразования к числу) можно воспользоваться функцией [[api:qpage:values#DirtyValue]]. Она может быть полезна при передаче фильтра целиком через коллекцию //Values//. Но в этом случае необходимо при формировании фильтра удостоверится в невозможности [[http://ru.wikipedia.org/wiki/%D0%92%D0%BD%D0%B5%D0%B4%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_SQL-%D0%BA%D0%BE%D0%B4%D0%B0|SQL-инъекции]]. Добавить программно новое значение можно с помощью функции [[api:qpage:values#AddValue]]. Не рекомендуется прямая работа с коллекцией //Values//, лучше использовать [[api:qpage:values|функции доступа]], упомянутые ранее в этом разделе.