Zend_Controller-ActionHelpers-ContextSwitch.xml 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- Reviewed: no -->
  3. <sect3 id="zend.controller.actionhelpers.contextswitch">
  4. <title>ContextSwitch и AjaxContext</title>
  5. <para>
  6. Помощник действий <code>ContextSwitch</code> предназначен для облегчения
  7. возврата ответов в различных форматах.
  8. Помощник <code>AjaxContext</code> является специализированной версией
  9. <code>ContextSwitch</code>, которая облегчает возврат ответа на запросы,
  10. произведенные посредством XmlHttpRequest.
  11. </para>
  12. <para>
  13. Для того, чтобы включить использование какого-либо из этих помощников,
  14. нужно указать в своем контроллере, какие действия могут отвечать в каком
  15. контексте. Если входящий запрос означает допустимый контекст для данного
  16. действия, то помощник производит следующие действия:
  17. </para>
  18. <itemizedlist>
  19. <listitem><para>
  20. Выключает макеты, если они включены.
  21. </para></listitem>
  22. <listitem><para>
  23. Устанавливает альтернативный суффикс вида, это позволяет эффективно
  24. разделять скрипты видов для различных контекстов.
  25. </para></listitem>
  26. <listitem><para>
  27. Отправляет HTTP-заголовки ответа, требуемые в данном контексте.
  28. </para></listitem>
  29. <listitem><para>
  30. Опционально вызывает предопределенные функции обратного вызова для
  31. установки контекста и/или пост-обработки.
  32. </para></listitem>
  33. </itemizedlist>
  34. <para>
  35. В качестве примера рассмотрим следующий контроллер:
  36. </para>
  37. <programlisting language="php"><![CDATA[
  38. class NewsController extends Zend_Controller_Action
  39. {
  40. /**
  41. * Начальная страница, производится переход к listAction()
  42. */
  43. public function indexAction()
  44. {
  45. $this->_forward('list');
  46. }
  47. /**
  48. * Выводит список новостей
  49. */
  50. public function listAction()
  51. {
  52. }
  53. /**
  54. * Просмотр одной новости
  55. */
  56. public function viewAction()
  57. {
  58. }
  59. }
  60. ]]></programlisting>
  61. <para>
  62. Предположим, нам нужно, чтобы действие <code>listAction()</code> было
  63. доступно и в формате XML. Вместо того, чтобы создавать новое действие,
  64. мы можем указать, что действие <code>listAction()</code> может
  65. возвращать и ответ в формате XML:
  66. </para>
  67. <programlisting language="php"><![CDATA[
  68. class NewsController extends Zend_Controller_Action
  69. {
  70. public function init()
  71. {
  72. $contextSwitch = $this->_helper->getHelper('contextSwitch');
  73. $contextSwitch->addActionContext('list', 'xml')
  74. ->initContext();
  75. }
  76. // ...
  77. }
  78. ]]></programlisting>
  79. <para>
  80. Этим будет:
  81. </para>
  82. <itemizedlist>
  83. <listitem><para>
  84. Установлен заголовок ответа 'Content-Type' со значением
  85. 'text/xml'.
  86. </para></listitem>
  87. <listitem><para>
  88. Изменено значение суффикса вида на 'xml.phtml' (или
  89. 'xml.[your suffix]', если вы используете другой суффикс вида).
  90. </para></listitem>
  91. </itemizedlist>
  92. <para>
  93. Теперь нужно создать новый скрипт вида - 'news/list.xml.phtml',
  94. в котором формируется код XML.
  95. </para>
  96. <para>
  97. Для определения того, нужно ли переключение контекста,
  98. помощник проверяет метку в объекте запроса. По умолчанию он
  99. проверяет параметр 'format', но это поведение может быть изменено.
  100. Это значит, что в большинстве случаев для того, чтобы инициировать
  101. переключение контекста, достаточно добавить параметр 'format' в
  102. запрос одним из двух способов:
  103. </para>
  104. <itemizedlist>
  105. <listitem><para>
  106. Через параметр URL: <code>/news/list/format/xml</code>
  107. (напоминаем, используемый по умолчанию механизм маршрутизации
  108. разрешает добавление произвольных пар ключ/значение после
  109. имени действия в URL)
  110. </para></listitem>
  111. <listitem><para>
  112. Через параметр GET: <code>/news/list?format=xml</code>
  113. </para></listitem>
  114. </itemizedlist>
  115. <para>
  116. <code>ContextSwitch</code> позволяет задавать любой контекст, включая
  117. используемый суффикс вида, отправляемые заголовки ответа и функции
  118. обратного вызова для инициализации и пост-обработки.
  119. </para>
  120. <sect4 id="zend.controller.actionhelpers.contextswitch.contexts">
  121. <title>Доступные по умолчанию контексты</title>
  122. <para>
  123. По умолчанию через помощник <code>ContextSwitch</code> используются
  124. два контекста: json и xml.
  125. </para>
  126. <itemizedlist>
  127. <listitem>
  128. <para>
  129. <emphasis>JSON</emphasis>. Контекст JSON устанавливает
  130. заголовок ответа 'Content-Type' в значение
  131. 'application/json' и суффикс скрипта вида в значение
  132. 'json.phtml'.
  133. </para>
  134. <para>
  135. Но по умолчанию использование скриптов вида не обязательно.
  136. Контекст просто сериализует все переменные вида и сразу
  137. возвращает ответ в формате JSON.
  138. </para>
  139. <para>
  140. Это поведение может быть отменено путем отключения
  141. автоматической сериализации JSON:
  142. </para>
  143. <programlisting language="php"><![CDATA[
  144. $this->_helper->contextSwitch()->setAutoJsonSerialization(false);
  145. ]]></programlisting>
  146. </listitem>
  147. <listitem>
  148. <para>
  149. <emphasis>XML</emphasis>. Контекст XML устанавливает
  150. заголовок ответа 'Content-Type' в значение 'text/xml' и
  151. суффикс скрипта вида в значение 'xml.phtml'. Для этого
  152. контекста нужно создавать скрипты вида.
  153. </para>
  154. </listitem>
  155. </itemizedlist>
  156. </sect4>
  157. <sect4 id="zend.controller.actionhelpers.contextswitch.custom">
  158. <title>Создание своего контекста</title>
  159. <para>
  160. Иногда доступных по умолчанию контекстов может быть недостаточно.
  161. Например, нужно возвращать данные в формате YAML, сериализованный
  162. PHP, ленты RSS, ATOM и т.д. <code>ContextSwitch</code> позволяет
  163. добавлять новые контексты.
  164. </para>
  165. <para>
  166. Наиболее простым способом добавления нового контекста является
  167. использование метода <code>addContext()</code>. Этот метод
  168. принимает два аргумента - имя контекста и массив спецификации.
  169. Массив должен включать в себя один или более элементов
  170. из следующих:
  171. </para>
  172. <itemizedlist>
  173. <listitem>
  174. <para><emphasis>suffix</emphasis>: суффикс, который должен
  175. добавляться перед суффиксом, зарегистрированным во
  176. ViewRenderer.</para>
  177. </listitem>
  178. <listitem>
  179. <para><emphasis>headers</emphasis>: массив пар
  180. заголовок/значение, которые требуется отправлять в
  181. ответе.</para>
  182. </listitem>
  183. <listitem>
  184. <para><emphasis>callbacks</emphasis>: массив, который содержит
  185. ключи 'init' и 'post' (один из них или оба).
  186. Ключи должны указывать на действующие функции обратного вызова,
  187. которые могут использоваться для инициализации и пост-обработки
  188. контекста.</para>
  189. <para>Вызов функции инициализации производится сразу после
  190. того, как контекст определен помощником
  191. <code>ContextSwitch</code>. Вы можете использовать его для
  192. выполнения произвольной логики. Например, контекст JSON
  193. использует функцию обратного вызова для отключения
  194. ViewRenderer, если включена автоматическая сериализация
  195. JSON.</para>
  196. <para>Вызов функции пост-обработки производится во время
  197. операции <code>postDispatch()</code> и может использоваться для
  198. выполнения произвольной логики. Например, контекст JSON
  199. использует функцию обратного вызова для определения того,
  200. включена ли автоматическая сериализация JSON; если включена, то
  201. помощник сериализует переменные вида в JSON и отправляет ответ,
  202. иначе включается ViewRenderer.</para>
  203. </listitem>
  204. </itemizedlist>
  205. <para>
  206. Для взаимодействия с контекстом есть несколько методов:
  207. </para>
  208. <itemizedlist>
  209. <listitem><para>
  210. <code>addContext($context, array $spec)</code>: добавляет новый
  211. контекст. Бросает исключение, если контекст уже существует.
  212. </para></listitem>
  213. <listitem><para>
  214. <code>setContext($context, array $spec)</code>: добавляет новый
  215. контекст или переопределяет существующий. Использует ту же
  216. спецификацию, что и <code>addContext()</code>.
  217. </para></listitem>
  218. <listitem><para>
  219. <code>addContexts(array $contexts)</code>: добавляет несколько
  220. контекстов одновременно. Массив <varname>$contexts</varname> должен
  221. содержать пары контекст/спецификация. Если какой-либо из
  222. контекстов уже существует, то бросается исключение.
  223. </para></listitem>
  224. <listitem><para>
  225. <code>setContexts(array $contexts)</code>: добавляет новые
  226. контексты и переопределяет существующие. Использует ту же
  227. спецификацию, что и <code>addContexts()</code>.
  228. </para></listitem>
  229. <listitem><para>
  230. <code>hasContext($context)</code>: если контекст с этим именем
  231. уже существует, то метод возвращает true, иначе false.
  232. </para></listitem>
  233. <listitem><para>
  234. <code>getContext($context)</code>: возвращает контекст по его
  235. имени в виде массива, следующего спецификации, используемой
  236. в <code>addContext()</code>.
  237. </para></listitem>
  238. <listitem><para>
  239. <code>getContexts()</code>: возвращает все контексты в виде
  240. массива пар контекст/спецификация.
  241. </para></listitem>
  242. <listitem><para>
  243. <code>removeContext($context)</code>: удаляет контекст
  244. по его имени. Возвращает true в случае успеха, false - если
  245. контекст не найден.
  246. </para></listitem>
  247. <listitem><para>
  248. <code>clearContexts()</code>: удаляет все контексты.
  249. </para></listitem>
  250. </itemizedlist>
  251. </sect4>
  252. <sect4 id="zend.controller.actionhelpers.contextswitch.actions">
  253. <title>Установка контекстов для действий</title>
  254. <para>
  255. Есть два способа установки доступных для действий контекстов.
  256. Вы можете либо вручную создавать массивы в своем контроллере, либо
  257. использовать несколько методов в <code>ContextSwitch</code> для
  258. "сборки" таких массивов.
  259. </para>
  260. <para>
  261. <code>addActionContext()</code> является основным методом для
  262. добавления связей действие/контекст. Он принимает два аргумента:
  263. действие, к которому добавляется контекст, и имя контекста (либо
  264. массив контекстов). Для примера рассмотрим следующий класс
  265. контроллера:
  266. </para>
  267. <programlisting language="php"><![CDATA[
  268. class FooController extends Zend_Controller_Action
  269. {
  270. public function listAction()
  271. {
  272. }
  273. public function viewAction()
  274. {
  275. }
  276. public function commentsAction()
  277. {
  278. }
  279. public function updateAction()
  280. {
  281. }
  282. }
  283. ]]></programlisting>
  284. <para>
  285. Предположим, что мы хотим добавить контекст XML к действию 'list',
  286. а к действию 'comments' - контексты XML и JSON. В этом случае мы
  287. можем добавить следующий код в метод <code>init()</code>:
  288. </para>
  289. <programlisting language="php"><![CDATA[
  290. class FooController extends Zend_Controller_Action
  291. {
  292. public function init()
  293. {
  294. $this->_helper->contextSwitch()
  295. ->addActionContext('list', 'xml')
  296. ->addActionContext('comments', array('xml', 'json'))
  297. ->initContext();
  298. }
  299. }
  300. ]]></programlisting>
  301. <para>
  302. Мы можем также просто определить свойство <varname>$contexts</varname>
  303. в контроллере:
  304. </para>
  305. <programlisting language="php"><![CDATA[
  306. class FooController extends Zend_Controller_Action
  307. {
  308. public $contexts = array(
  309. 'list' => array('xml'),
  310. 'comments' => array('xml', 'json')
  311. );
  312. public function init()
  313. {
  314. $this->_helper->contextSwitch()->initContext();
  315. }
  316. }
  317. ]]></programlisting>
  318. <para>
  319. Этот способ менее трудоемкий, но заключает в себе больше
  320. потенциальных ошибок.
  321. </para>
  322. <para>
  323. Следующие методы могут использоваться для построения связей
  324. действие/контекст:
  325. </para>
  326. <itemizedlist>
  327. <listitem>
  328. <para>
  329. <code>addActionContext($action, $context)</code>: помечает
  330. один или более контекстов как доступные для действия
  331. $action. Если связи уже существуют, то производится
  332. добавление к ним. <varname>$context</varname> может быть как
  333. одним контекстом, так и массивом контекстов.
  334. </para>
  335. <para>
  336. Если <varname>$context</varname> имеет значение <constant>TRUE</constant>,
  337. то все доступные в <code>ContextSwitch</code> контексты
  338. помечаются как доступные для действия.
  339. </para>
  340. <para>
  341. Пустое значение аргумента <varname>$context</varname> отключит
  342. все контексты для данного действия.
  343. </para>
  344. </listitem>
  345. <listitem><para>
  346. <code>setActionContext($action, $context)</code>: помечает
  347. один или более контекстов как доступные для действия
  348. $action. Если связи уже существуют, то метод заменяет их
  349. указанными.
  350. <varname>$context</varname> может быть как одним контекстом, так и
  351. массивом контекстов.
  352. </para></listitem>
  353. <listitem><para>
  354. <code>addActionContexts(array $contexts)</code>: добавляет
  355. одновременно несколько пар действие/контекст.
  356. <varname>$contexts</varname> должен быть ассоциативным массивом
  357. пар действие/контекст. Использует метод
  358. <code>addActionContext()</code>, это означает, что если
  359. связи для данного действия уже существуют, то указанные в
  360. <varname>$contexts</varname> связи добавляются к ним.
  361. </para></listitem>
  362. <listitem><para>
  363. <code>setActionContexts(array $contexts)</code>: действует
  364. аналогично <code>addActionContexts()</code>, но
  365. переопределяет пары действие/контекст, если они уже
  366. существуют.
  367. </para></listitem>
  368. <listitem><para>
  369. <code>hasActionContext($action, $context)</code>:
  370. используется для определения того, имеет ли действие $action
  371. данный контекст.
  372. </para></listitem>
  373. <listitem><para>
  374. <code>getActionContexts($action = null)</code>: возвращает
  375. все контексты для действия $action или все пары
  376. действие/контекст.
  377. </para></listitem>
  378. <listitem><para>
  379. <code>removeActionContext($action, $context)</code>:
  380. удаляет один или более контекстов из действия $action.
  381. <varname>$context</varname> может быть как
  382. одним контекстом, так и массивом контекстов.
  383. </para></listitem>
  384. <listitem><para>
  385. <code>clearActionContexts($action = null)</code>: удаляет
  386. все контексты из действия $action или из всех
  387. действий с контекстами.
  388. </para></listitem>
  389. </itemizedlist>
  390. </sect4>
  391. <sect4 id="zend.controller.actionhelpers.contextswitch.initcontext">
  392. <title>Инициализация переключения контекста</title>
  393. <para>
  394. Для того, чтобы инициализировать переключение контекста, необходимо
  395. вызвать метод <code>initContext()</code> в контроллере действий:
  396. </para>
  397. <programlisting language="php"><![CDATA[
  398. class NewsController extends Zend_Controller_Action
  399. {
  400. public function init()
  401. {
  402. $this->_helper->contextSwitch()->initContext();
  403. }
  404. }
  405. ]]></programlisting>
  406. <para>
  407. В некоторых случаях может потребоваться принудительное использование
  408. контекста - например, использовать только контекст XML, если
  409. переключение контекста включено. Вы можете осуществить это
  410. передачей контекста методу <code>initContext()</code>:
  411. </para>
  412. <programlisting language="php"><![CDATA[
  413. $contextSwitch->initContext('xml');
  414. ]]></programlisting>
  415. </sect4>
  416. <sect4 id="zend.controller.actionhelpers.contextswitch.misc">
  417. <title>Дополнительный функционал</title>
  418. <para>
  419. Для управления помощником <code>ContextSwitch</code> могут
  420. использоваться различные методы. Эти методы включают в себя:
  421. </para>
  422. <itemizedlist>
  423. <listitem>
  424. <para>
  425. <code>setAutoJsonSerialization($flag)</code>: По умолчанию
  426. контекст JSON будет сериализовать все переменные вида
  427. согласно нотации JSON и возвращать их в качестве ответа.
  428. Если вы хотите самостоятельно формировать ответ, то должны
  429. отключить автоматическую сериализацию через данный метод;
  430. это нужно делать до вызова <code>initContext()</code>.
  431. </para>
  432. <programlisting language="php"><![CDATA[
  433. $contextSwitch->setAutoJsonSerialization(false);
  434. $contextSwitch->initContext();
  435. ]]></programlisting>
  436. <para>
  437. Вы можете получить значение этого флага через метод
  438. <code>getAutoJsonSerialization()</code>.
  439. </para>
  440. </listitem>
  441. <listitem>
  442. <para>
  443. <code>setSuffix($context, $suffix,
  444. $prependViewRendererSuffix)</code>: Используя этот
  445. метод, вы можете задать другой суффикс для использования в
  446. контексте $context. Третий аргумент используется для
  447. указания того, добавлять ли или нет суффикс из
  448. помощника ViewRenderer к новому суффиксу; этот флаг
  449. установлен по умолчанию.
  450. </para>
  451. <para>
  452. Передача пустого значения в качестве суффикса приведет к
  453. тому, что будет использоваться только суффикс из
  454. ViewRenderer.
  455. </para>
  456. </listitem>
  457. <listitem>
  458. <para>
  459. <code>addHeader($context, $header, $content)</code>:
  460. Добавляет заголовок ответа для контекста $context.
  461. <varname>$header</varname> является именем заголовка, а
  462. <varname>$content</varname> - значением для этого заголовка.
  463. </para>
  464. <para>
  465. Любой контекст может иметь несколько заголовков.
  466. <code>addHeader()</code> добавляет дополнительные
  467. заголовки в стек заголовков для данного контекста.
  468. </para>
  469. <para>
  470. Если переданный заголовок уже существует для данного
  471. контекста, то бросается исключение.
  472. </para>
  473. </listitem>
  474. <listitem>
  475. <para>
  476. <code>setHeader($context, $header, $content)</code>:
  477. <code>setHeader()</code> действует аналогично
  478. <code>addHeader()</code> за исключением того, что позволяет
  479. переопределять существующие для данного контекста заголовки.
  480. </para>
  481. </listitem>
  482. <listitem>
  483. <para>
  484. <code>addHeaders($context, array $headers)</code>:
  485. Добавляет несколько заголовков к контексту $context.
  486. Использует <code>addHeader()</code>, поэтому
  487. если заголовок уже существует, то бросается исключение.
  488. <varname>$headers</varname> является массивом пар
  489. заголовок/значение.
  490. </para>
  491. </listitem>
  492. <listitem>
  493. <para>
  494. <code>setHeaders($context, array $headers.)</code>:
  495. действует аналогично <code>addHeaders()</code> за
  496. исключением того, что использует <code>setHeader()</code>,
  497. что позволяет перезаписывать существующие заголовки.
  498. </para>
  499. </listitem>
  500. <listitem>
  501. <para>
  502. <code>getHeader($context, $header)</code>: возвращает
  503. значение заголовка для данного контекста. Если заголовок
  504. не найден, то возвращается null.
  505. </para>
  506. </listitem>
  507. <listitem>
  508. <para>
  509. <code>removeHeader($context, $header)</code>: удаляет
  510. один заголовок для данного контекста.
  511. </para>
  512. </listitem>
  513. <listitem>
  514. <para>
  515. <code>clearHeaders($context)</code>: удаляет все
  516. заголовки для данного контекста.
  517. </para>
  518. </listitem>
  519. <listitem>
  520. <para>
  521. <code>setCallback($context, $trigger, $callback)</code>:
  522. устанавливает функцию обратного вызова для триггера $trigger
  523. и контекста $context. Триггерами могут быть 'init' или
  524. 'post' (выбор триггера определяет, когда будет вызвана
  525. функция - во время инициализации контекста или операции
  526. <code>postDispatch()</code>). <varname>$callback</varname> должен
  527. быть действующей PHP-функцией обратного вызова.
  528. </para>
  529. </listitem>
  530. <listitem>
  531. <para>
  532. <code>setCallbacks($context, array $callbacks)</code>:
  533. устанавливает несколько функций обратного вызова для
  534. данного контекста. <varname>$callbacks</varname> должен быть
  535. массивом пар триггер/функция обратного вызова. В
  536. действительности можно зарегистрировать максимум две
  537. функции обратного вызова, одна для инициализации, другая для
  538. пост-обработки.
  539. </para>
  540. </listitem>
  541. <listitem>
  542. <para>
  543. <code>getCallback($context, $trigger)</code>: возвращает
  544. функцию обратного вызова для триггера $trigger и контекста
  545. $context.
  546. </para>
  547. </listitem>
  548. <listitem>
  549. <para>
  550. <code>getCallbacks($context)</code>: возвращает все функции
  551. обратного вызова в виде массива пар триггер/функция
  552. обратного вызова.
  553. </para>
  554. </listitem>
  555. <listitem>
  556. <para>
  557. <code>removeCallback($context, $trigger)</code>: удаляет
  558. функцию обратного вызова для триггера $trigger и контекста
  559. $context.
  560. </para>
  561. </listitem>
  562. <listitem>
  563. <para>
  564. <code>clearCallbacks($context)</code>: удаляет все функции
  565. обратного вызова для данного контекста.
  566. </para>
  567. </listitem>
  568. <listitem>
  569. <para>
  570. <code>setContextParam($name)</code>: устанавливает параметр
  571. запроса, используемый для переключения контекста. По
  572. умолчанию установлено значение 'format', но его можно
  573. изменить с помощью данного аксессора.
  574. </para>
  575. <para>
  576. <code>getContextParam()</code> может использоваться для
  577. получения текущего значения.
  578. </para>
  579. </listitem>
  580. <listitem>
  581. <para>
  582. <code>setAutoDisableLayout($flag)</code>: По умолчанию
  583. макеты отключаются, когда производится переключение
  584. контекста. Это потому, что макеты, как правило, используются
  585. только с обычным выводом и их использование не имеет смысла
  586. для альтернативного контекста. Тем не менее, если вы хотите
  587. использовать макеты, то можете изменить это поведение,
  588. передав значение <constant>FALSE</constant> методу
  589. <code>setAutoDisableLayout()</code>. Вы должны делать это
  590. <emphasis>до</emphasis> вызова <code>initContext()</code>.
  591. </para>
  592. <para>
  593. Для получения значения этого флага используйте аксессор
  594. <code>getAutoDisableLayout()</code>.
  595. </para>
  596. </listitem>
  597. <listitem>
  598. <para>
  599. <code>getCurrentContext()</code> может использоваться
  600. для определения того, какой контекст был установлен.
  601. Возвращает null, если не было переключения контекста,
  602. или метод был вызван до <code>initContext()</code>.
  603. </para>
  604. </listitem>
  605. </itemizedlist>
  606. </sect4>
  607. <sect4 id="zend.controller.actionhelpers.contextswitch.ajaxcontext">
  608. <title>Функционал AjaxContext</title>
  609. <para>
  610. Помощник <code>AjaxContext</code> наследует от
  611. <code>ContextSwitch</code>, поэтому весь функционал, описанный
  612. для <code>ContextSwitch</code>, доступен и для него. Но есть
  613. несколько ключевых отличий.
  614. </para>
  615. <para>
  616. Во-первых, он использует другое свойство контроллера для
  617. определения контекстов, а именно <varname>$ajaxable</varname>. Поэтому вы
  618. можете одновременно использовать различные контексты для AJAX и
  619. обычных HTTP-запросов. Все методы
  620. <code>*ActionContext*()</code> помощника <code>AjaxContext</code>
  621. будут записывать в это свойство.
  622. </para>
  623. <para>
  624. Во-вторых, он будет запускаться только тогда, когда производится
  625. запрос XmlHttpRequest. Для определения того, был ли произведен
  626. запрос XmlHttpRequest, используется метод
  627. <code>isXmlHttpRequest()</code> объекта запроса.
  628. Таким образом, если параметр контекста ('format') был передан в
  629. запросе, но сам запрос был произведен не через
  630. XmlHttpRequest, то не будет произведено переключение контекста.
  631. </para>
  632. <para>
  633. И в-третьих, <code>AjaxContext</code> добавляет дополнительный
  634. контекст - HTML. В этом контексте он устанавливает суффикс в
  635. значение 'ajax.phtml' для отделения этого контекста от обычных
  636. запросов. Дополнительные заголовки не возвращаются.
  637. </para>
  638. <example id="zend.controller.actionhelpers.contextswitch.ajaxcontext.example">
  639. <title>Установка действий для ответов на AJAX-запросы</title>
  640. <para>
  641. В следующем примере мы указываем, что действия 'view', 'form' и
  642. 'process' могут отвечать на AJAX-запросы. В действиях
  643. 'view' и 'form' мы будем возвращать куски HTML-кода для
  644. обновления страницы, в действии 'process' - данные в формате
  645. JSON.
  646. </para>
  647. <programlisting language="php"><![CDATA[
  648. class CommentController extends Zend_Controller_Action
  649. {
  650. public function init()
  651. {
  652. $ajaxContext = $this->_helper->getHelper('AjaxContext');
  653. $ajaxContext->addActionContext('view', 'html')
  654. ->addActionContext('form', 'html')
  655. ->addActionContext('process', 'json')
  656. ->initContext();
  657. }
  658. public function viewAction()
  659. {
  660. // Извлекает один комментарий для просмотра
  661. // Если определен контекст AjaxContext, то используется
  662. // скрипт вида comment/view.ajax.phtml
  663. }
  664. public function formAction()
  665. {
  666. // Рендерит форму для добавления нового комментария
  667. // Если определен контекст AjaxContext, то используется
  668. // скрипт вида comment/form.ajax.phtml
  669. }
  670. public function processAction()
  671. {
  672. // Обрабатывает новый комментарий
  673. // Возвращает результат в формате JSON. Просто присвойте значения
  674. // переменным вида и эти значения будет возвращены в формате JSON.
  675. }
  676. }
  677. ]]></programlisting>
  678. <para>
  679. На клиентской стороне посредством AJAX-библиотеки производятся
  680. запросы к конечным точкам '/comment/view',
  681. '/comment/form', '/comment/process' и передается параметр
  682. 'format': '/comment/view/format/html',
  683. '/comment/form/format/html', '/comment/process/format/json'
  684. (можно также передавать параметр
  685. через строку запроса, например: "?format=json").
  686. </para>
  687. <para>
  688. Если ваша AJAX-библиотека передает заголовок 'X-Requested-With:
  689. XmlHttpRequest', то эти действия будут возвращать ответ в
  690. требуемом формате.
  691. </para>
  692. </example>
  693. </sect4>
  694. </sect3>
  695. <!--
  696. vim:se ts=4 sw=4 et:
  697. -->