[ZF-10089] Zend_Log
[zend.git] / documentation / manual / zh / module_specs / Zend_Controller-ActionHelpers-AutoComplete.xml
bloba753addb48747b9828cb847fed0299823b077eae
1 <sect3 id="zend.controller.actionhelpers.autocomplete">
2     <title>AutoComplete</title>
4     <para>
5         许多 AJAX javascript 函数库提供了以潜在地匹配结果的选择列表作为用户类别显示的自动完成。<code>AutoComplete</code> 助手简化返回可接受的响应给这样的方法。
6     </para>
8     <para>
9         因为并非所有的 JS 库用同样的方法实现自动完成,<code>AutoComplete</code> 助手提供了一些必要的基本的摘要函数给这些库并对个别库提供了具体实现。返回类型一般是 JSON 字符串数组、JSON 数组的数组 (每个成员的数组是一个用于创建选择列表的元数据(metadata)的关联数组) 或 HTML。
10     </para>
12     <para>
13         每个实现的基本用法都一样:
14     </para>
16         <programlisting role="php"><![CDATA[
17 class FooController extends Zend_Controller_Action
19     public function barAction()
20     {
21         // Perform some logic...
23         // Encode and send response;
24         $this->_helper->autoCompleteDojo($data);
26         // Or explicitly:
27         $response = $this->_helper->autoCompleteDojo
28                                   ->sendAutoCompletion($data);
30         // Or simply prepare autocompletion response:
31         $response = $this->_helper->autoCompleteDojo
32                                   ->prepareAutoCompletion($data);
33     }
35 ]]>
36         </programlisting>
38     <para>
39         缺省地,自动完成做这些工作:
40     </para>
42     <itemizedlist>
43         <listitem><para>
44                 关闭布局(layouts)和视图解析器(ViewRenderer)。
45         </para></listitem>
47         <listitem><para>
48                 设置合适的响应头。
49         </para></listitem>
51         <listitem><para>
52                 用编码的/格式化的自动完成数据设置响应体。
53         </para></listitem>
55         <listitem><para>
56                 发送响应。
57         </para></listitem>
58     </itemizedlist>
60     <para>
61         可用的助手方法包括:
62     </para>
64     <itemizedlist>
65         <listitem><para>
66                 <code>disableLayouts()</code> 用来关闭布局和视图解析器。一般地,在 <code>prepareAutoCompletion()</code> 里调用它。
67         </para></listitem>
69         <listitem><para>
70                 <code>encodeJson($data, $keepLayouts = false)</code> 给 JSON 编码,可选打开或关闭布局。一般地,在 <code>prepareAutoCompletion()</code> 里调用它。
71         </para></listitem>
73         <listitem><para>
74                 <code>prepareAutoCompletion($data, $keepLayouts = false)</code> 用来为具体实现以响应格式准备数据,可选地打开或关闭布局,返回值因不同的实现而不同。
75         </para></listitem>
77         <listitem><para>
78                 <code>sendAutoCompletion($data, $keepLayouts = false)</code> 用来为具体实现发送响应格式的数据,它调用 <code>prepareAutoCompletion()</code>,然后发送响应。
79         </para></listitem>
81         <listitem><para>
82                 当把助手作为助手代理的方法来调用,使用 <code>direct($data, $sendNow = true, $keepLayouts = false)</code> 。The <code>$sendNow</code> flag 用来决定是否分别调用 <code>sendAutoCompletion()</code> 或 <code>prepareAutoCompletion()</code>。
83         </para></listitem>
84     </itemizedlist>
86     <para>
87         目前 <code>AutoComplete</code> 支持 Dojo 和 Scriptaculous AJAX 库。
88     </para>
90     <sect4 id="zend.controller.actionhelpers.autocomplete.dojo">
91         <title>AutoCompletion with Dojo</title>
93         <para>
94             Dojo 本身没有 AutoCompletion 小部件,但有两个小部件可以执行 AutoCompletion:ComboBox 和 FilteringSelect。对于这两者,都要求实现 QueryReadStore 的数据存储,关于这话题的更多信息参见 <ulink url="http://dojotoolkit.org/book/dojo-book-0-9/part-3-programmatic-dijit-and-dojo/data-retrieval-dojo-data-0">dojo.data</ulink> 文档。
95         </para>
97         <para>
98             在 Zend Framework 中,可以传递简单的索引的数组给 AutoCompleteDojo 助手,它将返回一个适合和这样一个存储一起使用的 JSON 响应:
99         </para>
101         <programlisting role="php"><![CDATA[
102 // within a controller action:
103 $this->_helper->autoCompleteDojo($data);
105         </programlisting>
107         <example id="zend.controller.actionhelpers.autocomplete.dojo.example1">
108             <title>AutoCompletion with Dojo Using Zend MVC</title>
110             <para>
111                 AutoCompletion with Dojo 通过 Zend MVC 需要若干事项:为你想要 AutoCompletion 的 ComboBox 生成一个表单对象,服务于 AutoCompletion 结果的控制器动作,生成定制的 QueryReadStore 来连接到 AutoCompletion 动作和 javascript 的生成用于在服务器端初始化 AutoCompletion。
112              </para>
114             <para>
115                 首先,看一下必需的 javascript 。Dojo 为生成 OOP javascript 提供一个完整的框架,很像 Zend Framework 对于 PHP。它的部分功能是使用目录等级结构生成假的命名空间(pseudo-namespaces )。 我们将在和 Dojo 同一级目录创建一个 'custom' 目录,那是 Dojo 发行的一部分。 在目录里面,我们将创建 javascript 文件,TestNameReadStore.js  带有以下内容:
116             </para>
118             <programlisting role="javascript"><![CDATA[
119 dojo.provide("custom.TestNameReadStore");
120 dojo.declare("custom.TestNameReadStore", dojox.data.QueryReadStore, {
121     fetch:function (request) {
122         request.serverQuery = { test:request.query.name };
123         return this.inherited("fetch", arguments);
124     }
127 </programlisting>
129             <para>
130                 该类是 Dojo 自己的 QueryReadStore 的扩展,QueryReadStore 是一个抽象类。我们简单地通过请求定义一个方法,并把它分配给 'test' 元素。
131             </para>
133             <para>
134                 下一步,为我们想要的 AutoCompletion 生成表单元素:
135             </para>
137             <programlisting role="php"><![CDATA[
138 class TestController extends Zend_Controller_Action
140     protected $_form;
142     public function getForm()
143     {
144         if (null === $this->_form) {
145             $this->_form = new Zend_Form();
146             $this->_form->setMethod('get')
147                 ->setAction(
148                     $this->getRequest()->getBaseUrl() . '/test/process'
149                 )
150                 ->addElements(array(
151                     'test' => array('type' => 'text', 'options' => array(
152                         'filters'        => array('StringTrim'),
153                         'dojoType'       => array('dijit.form.ComboBox'),
154                         'store'          => 'testStore',
155                         'autoComplete'   => 'false',
156                         'hasDownArrow'   => 'true',
157                         'label' => 'Your input:',
158                     )),
159                     'go' => array('type' => 'submit',
160                                   'options' => array('label' => 'Go!'))
161                 ));
162         }
163         return $this->_form;
164     }
167             </programlisting>
169             <para>
170                 这里,我们用 'test' 和 'go' 方法生成表单。'test' 方法添加若干特别的 Dojo 专用的属性:dojoType、 store、 autoComplete 和 hasDownArrow。dojoType 用来指示我们在生成 comboBox,并且我们将把它链接到 'testStore' 的数据存储(键 'store')-- 稍后还有更多。指定 'autoComplete' 作为 false 告诉 Dojo 不要自动选择第一个匹配,但是要显示一个匹配列表。最后,'hasDownArrow' 生成和选择 box 类似的向下箭头,这样我们可以显示和隐藏匹配。
171             </para>
173             <para>
174                 让我们添加一个方法来显示表单,和处理 AutoCompletion 的结束点:
175             </para>
177             <programlisting role="php"><![CDATA[
178 class TestController extends Zend_Controller_Action
180     // ...
182     /**
183      * Landing page
184      */
185     public function indexAction()
186     {
187         $this->view->form = $this->getForm();
188     }
190     public function autocompleteAction()
191     {
192         if ('ajax' != $this->_getParam('format', false)) {
193             return $this->_helper->redirector('index');
194         }
195         if ($this->getRequest()->isPost()) {
196             return $this->_helper->redirector('index');
197         }
199         $match = trim($this->getRequest()->getQuery('test', ''));
201         $matches = array();
202         foreach ($this->getData() as $datum) {
203             if (0 === strpos($datum, $match)) {
204                 $matches[] = $datum;
205             }
206         }
207         $this->_helper->autoCompleteDojo($matches);
208     }
211             </programlisting>
213             <para>
214                 在 <code>autocompleteAction()</code> 中我们做许多事情。首先,我们注意确保我们有个 post 请求,并且有个 'format' 参数的值为 'ajax';这样减少欺骗查询给动作。接着,我们检查 'test' 参数,并和我们的数据比较。(我在这里故意忽略了 <code>getData()</code> 的实现 -- 它可以是任何数据源)。最后,发送匹配给 AutoCompletion 助手。
215             </para>
217             <para>
218                 既然我们在后台有了所有的东西,来看一下在视图脚本中对于 landing 页面我们需要提交什么。 首先,我们需要设置数据存储,然后解析表单,最后确保合适的 Dojo 库被加载 --包括定制的数据存储。来看看视图脚本,步骤在注释里:
219             </para>
221             <programlisting role="php"><![CDATA[
222 <? // setup our data store: ?>
223 <div dojoType="custom.TestNameReadStore" jsId="testStore"
224     url="<?= $this->baseUrl() ?>/unit-test/autocomplete/format/ajax"
225     requestMethod="get"></div>
227 <? // render our form: ?>
228 <?= $this->form ?>
230 <? // setup Dojo-related CSS to load in HTML head: ?>
231 <? $this->headStyle()->captureStart() ?>
232 @import "<?= $this->baseUrl() ?>/javascript/dijit/themes/tundra/tundra.css";
233 @import "<?= $this->baseUrl() ?>/javascript/dojo/resources/dojo.css";
234 <? $this->headStyle()->captureEnd() ?>
236 <? // setup javascript to load in HTML head, including all required
237    // Dojo libraries: ?>
238 <? $this->headScript()
239         ->setAllowArbitraryAttributes(true)
240         ->appendFile($this->baseUrl() . '/javascript/dojo/dojo.js',
241             'text/javascript',
242             array('djConfig' => 'parseOnLoad: true'))
243         ->captureStart() ?>
244 djConfig.usePlainJson=true;
245 dojo.registerModulePath("custom","../custom");
246 dojo.require("dojo.parser");
247 dojo.require("dojox.data.QueryReadStore");
248 dojo.require("dijit.form.ComboBox");
249 dojo.require("custom.TestNameReadStore");
250 <? $this->headScript()->captureEnd() ?>
252             </programlisting>
254             <para>
255                 注意对视图助手的调用如 headStyle 和 headScript,它们是占位符,我们可以在布局视图脚本的 HTML 头中解析。
256             </para>
258             <para>
259                 现在所有的 Dojo AutoCompletion 开始工作了。
260             </para>
261         </example>
262     </sect4>
264     <sect4 id="zend.controller.actionhelpers.autocomplete.scriptaculous">
265         <title>AutoCompletion with Scriptaculous</title>
266         <para>
267             <ulink url="http://wiki.script.aculo.us/scriptaculous/show/Ajax.Autocompleter">Scriptaculous</ulink> 需要一个特定格式的 HTML 响应。
268         </para>
270         <para>
271             和这个库一起使用的助手是 'AutoCompleteScriptaculous',给它提供一个数据数组,这个助手将生成兼容于 Ajax.Autocompleter  的 HTML 响应。
272         </para>
273     </sect4>
274 </sect3>
275 <!--
276 vim:se ts=4 sw=4 et: