如何构造Zend_Dojo xhrPost请求

时间:2010-03-02 14:40:33

标签: ajax zend-framework dojo xmlhttprequest

我是Dojo的新手。

请问如何在Zend中构建xhrPost请求?

2 个答案:

答案 0 :(得分:0)

我已经在XhrPost上使用了dojo一段时间了,这真的很棒。 ZF手册中没有太多内容,但我通过dojo manual建议的客户端来解决沟通问题。

我的ajax课程有点简化:

dojo.declare('fetch_dom_node_contents', null, {
    handleAs: "json",

    load: function(response, ioArgs){
        this.ajax_response = response;
        this._loadModules();
        var dom_node = dojo.byId(response.node_name)
        dojo.html.set(dom_node, response.content);
        return response;
    },

    /**
     * Since modules might be needed for the new element they should be loaded
     */
    _loadModules: function(){
        if(this.ajax_response.dojo_modules){
            dojo.forEach(this.ajax_response.dojo_modules,
                function(mod){
                    dojo.require(mod);
                });
        }
    }
});

我的控制器很简单,通过使用contextswitch,我的优点是无论何时在ajax JSON模式下,所有视图变量都会自动转换为JSON格式:

class IndexController extends Zend_Controller_Action
{
    public function init()
    {
        $this->view->headScript()->appendFile('/js/application/my_classes.js');

        $contextSwitch = $this->_helper->getHelper('contextSwitch');
        $contextSwitch
                ->addActionContext('get-content', array('json'))
                ->setAutoJsonSerialization( true )
                ->initContext();
    }

    public function indexAction()
    {
        //Stuff here ...
    }

    public function getContentAction(){
        $this->view->node_name = "my_node";
        $this->view->content = "Awesome content";
        $this->view->dojo_modules = $this->view->dojo()->getModules();
    }
}

最后我接到了get-content的调用:

dojo.xhrGet(new fetch_dom_node_contents("/index/get-content/format/json"));

这个我自己嵌入了som或按钮onClick()事件。重要的是拥有:

event.preventDefault();
event.stopPropagation();

在xhrGet()或xhrPost()之前。如果您的发布表单只需要在fetch_dom_node_contents类中添加表单:dojo.byId(“myform”),表单将被发送到您只需处理“照常营业”的控制器。

由于ajax提交表单通常会重定向或执行其他操作,因此您应该附加“/ format / json”或类似于提示的操作,它应该将json作为响应返回,而不是仅仅执行重定向。我有这个简单的动作助手来检查我是否在ajax调用中:

<?php

/**
 * Action Helper for checking if context is of json type
 *
 * @uses Zend_Controller_Action_Helper_Abstract
 */
class Action_Helper_IsJson extends Zend_Controller_Action_Helper_Abstract
{
        /**
         * Checks if the format parameter is set to json
         * if so it returns true
         * 
         */
        public function isJson(){
                $format = $this->getRequest()->getParam('format', false);
                if (strtolower($format) == "json"){
                        return true;
                }else{
                        return false;
                }
        }

        public function direct()
        {
                return $this->isJson();
        }
}

当我的表单被成功解析后,我有另一个帮助程序,只要有重定向就很方便:

<?php
/**
 *
 * @uses Zend_Controller_Action_Helper_Abstract
 */
class Action_Helper_SendReloadResponse extends Zend_Controller_Action_Helper_Abstract
{
        /**
         */
        public function sendReloadResponse($url){
                echo Zend_Json_Encoder::encode(array(
                        'success' => true,
                        'reloadHTTP' => $url)
                );
                die();
        }

        /**
         * @return boolean
         */
        public function direct($url)
        {
                return $this->sendReloadResponse($url);
        }
}

然后我在我的ajax加载部分a:

if (responseData.reloadHTTP) {
    // Probably first element or last element
    window.location = responseData.reloadHTTP;
}

嗯......我不知道这是否是处理xhrGet / Post的最佳方式,但它工作正常,也许你可以摆弄它,找到更好的解决方案并分享 - 我没有发现当想要从ajax,dojo和zend开始时。让我入门的是nanaeu但是那个代码(就像我的代码)现在还很老了:/

答案 1 :(得分:0)

我有一个更简单的方法。

在视图脚本中

<?php $this->dojo()->javascriptCaptureStart() ?>
function ajaxUpdate(url, targetNode, p1, p2) {
    // remove old content, prevents id clashing when generating new content.
    dojo.forEach(dijit.findWidgets(targetNode), function(win) {
        win.destroyRecursive();   
    });
    var xhrArgs = {
        url: url,
        handleAs: "text",
        content: {
            p1: p1,
            p2: p2
        },
        load: function(data) {
            dojo.html.set(targetNode, data, {parseContent: true});
        },
        error: function(error) {
            alert("An unexpected error occurred: " + error);
        }
    }
    dojo.xhrPost(xhrArgs);
}
<?php $this->dojo()->javascriptCaptureEnd() ?>

如果你做了很多AJAX并希望它出现在每个视图中,你也可以将它添加到布局脚本甚至引导程序文件中。

现在让您在视图中有一个id =“show-message”的按钮,并且您想要根据输入字段(id =“field1”)和复选框(id =“box1)的值加载自定义html “)到div(id =”put-message-here“)。然后,您还将在视图脚本中设置以下内容:

<?php $this->dojo()->onLoadCaptureStart() ?>
 function() {
    var field1 = dojo.byId("field1").value;
    var box1 = dojo.byId("box1").value;
    var url = "/module/controller/action/format/html";
    var targetNode = dojo.byId("put-message-here");

    dojo.connect(dojo.byId("show-message"), 'onclick', function() {
        ajaxUpdate(url, targetNode, field1, box1);
    });
 }
<?php $this->dojo()->onLoadCaptureEnd() ?>

在url中将替换模块,控制器,动作,无论指向你的动作来处理ajax调用。如果您没有设置模块,则需要将其设置为“default”,省略它似乎不起作用。

所以如果我们在indexController中设置了url =“/ default / index / ajaxform / format / html”:

class IndexController extends Zend_Controller_Action
{
    public function init()
    {
        // set actions for use with AJAX call.
        $ajaxContext = $this->_helper->getHelper('AjaxContext');
        $ajaxContext->addActionContext('ajaxform', 'html')
                    ->initContext();
    }

    public function ajaxformAction()
    {
        $field = $this->getRequest()->getParam('p1');
        $box = $this->getRequest()->getParam('p2');

        // logic goes here

        $this->view->some_var = $whatever;
    }

    ....

如您所见,我们的操作看起来像Zend中的任何其他操作。唯一的区别是,不是将其输出发送到ajaxform.phtml,而是将其发送到ajaxform.ajax.phtml(因为init()中使用了帮助器。所以现在在ajaxform.ajax.phtml中你有什么您希望在我们的目标div中显示的代码。

<p><?php echo $this->some_var; ?></p>

再次看起来像任何其他的视图。

我发现的唯一问题是我想创建的任何新的dojo dijits都必须以声明方式创建,这意味着我不能使用dojo视图助手。