Magento Ajax - 如何以编程方式从Controller显示自定义块(我的HTML内容始终为空)

Nat*_*ais 3 controller class block magento

我试图显示一个块作为响应ajax调用的一部分.一切正常,除了我无法让控制器回显模板HTML代码.

我的模块类:

class MyModule_Ajax_ProductController extends Mage_Catalog_ProductController {

    public function indexAction() {

        if ($product = $this->_initProduct()) {

            echo '<div>hello</div>'; //this works

            echo $this->getLayout()->createBlock('ajax/product')->setTemplate('mymodule_ajax/product.phtml')->toHtml();

            //I also tried:
            //$layout = $this->getLayout();
            //$update = $layout->getUpdate();
            //$update->load('ajax_product_index'); 
            //$layout->generateXml();
            //$layout->generateBlocks();
            //$output = $layout->getOutput();
            //echo $output;

        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在我的模板文件product.phtml中 - 这个HTML永远不会显示出来.(保存到app/design/frontend/default/default/template/mymodule_ajax/product.phtml)

<div>HERE!</div>
Run Code Online (Sandbox Code Playgroud)

我的块类:

class MyModule_Ajax_Block_Product extends Mage_Catalog_Block_Product
{
    private $product;

    protected function _construct()
    {
        parent::_construct();
        $this->setTemplate('mymodule_ajax/product.phtml');
    }

    protected function _toHtml() {
        return parent::_toHtml();
    }

    public function setProduct($product) {
        $this->product = $product;
        return $this;
    }

    public function getProduct() {
        return $this->product;
    }

}
Run Code Online (Sandbox Code Playgroud)

我的layout/mymodule_ajax.xml

<?xml version="1.0"?>
<layout>

    <ajax_product_index>
        <reference name="root">
            <block type="ajax/project" name="root" output="toHtml" template="mymodule_ajax/product.phtml"/>
        </reference>
    </ajax_product_index>

</layout>
Run Code Online (Sandbox Code Playgroud)

我假设因为我在块类中以编程方式设置模板我不应该需要模块引用?删除引用没有区别.

我没有得到PHP错误,HTML显示呈现

<html>
<head></head>
<body></body>
</html>
Run Code Online (Sandbox Code Playgroud)

我根本无法弄清楚我做错了什么?我正在使用Magento CE 1.8.1

Mal*_*chy 9

我发现这些事情非常困难.我将尝试分两部分回答:

第一部分

您可能想尝试在控制器中呈现布局,因此请先尝试此操作,然后阅读以下附加项:

//file: app/code/local/MyModule/Ajax/controllers/ProductController.php
//class: MyModule_Ajax_ProductController
//function: indexAction()
$this->loadLayout();
$this->renderLayout();
Run Code Online (Sandbox Code Playgroud)

但是你正在制作一个Ajax模块.所以你可能想要使用控制器方法,例如:

//set the response
$this->getResponse()
//->clearHeaders()
->setHeader('Content-Type', 'application/json')
->setBody(json_encode($someReturnObject));
    return;
Run Code Online (Sandbox Code Playgroud)

如果你想要setBody()一个块的HTML,那么在控制器中你上面发布的代码看起来很好(但请看下面的第二部分): -

  $this->loadLayout();
  $myBlock = $this->getLayout()->createBlock('ajax/product');
  $myBlock->setTemplate('mymodule_ajax/product.phtml');
  $myHtml =  $myBlock->toHtml(); //also consider $myBlock->renderView();     
  $this->getResponse()
       ->setHeader('Content-Type', 'text/html')
       ->setBody($myHtml);
  return;
Run Code Online (Sandbox Code Playgroud)

实际上即使只是exit();在结束时调用indexAction()也会将PHP输出缓冲区刷新到浏览器.

我注意到你正在制作一个产品控制器.研究您正在扩展的类中的代码可能会有所帮助:

//file: app/code/core/Mage/Catalog/controllers/ProductController.php
//class: Mage_Catalog_ProductController
//function: viewAction()
    public function viewAction()
    {
        // Get initial data from request
        $categoryId = (int) $this->getRequest()->getParam('category', false);
        $productId  = (int) $this->getRequest()->getParam('id');
        $specifyOptions = $this->getRequest()->getParam('options');

        // Prepare helper and params
        $viewHelper = Mage::helper('catalog/product_view');

        $params = new Varien_Object();
        $params->setCategoryId($categoryId);
        $params->setSpecifyOptions($specifyOptions);

        // Render page
        try {
            $viewHelper->prepareAndRender($productId, $this, $params);
        } catch (Exception $e) {
            //...
        }
    }
Run Code Online (Sandbox Code Playgroud)

这可能会给你一些关于将Magento标准产品相关HTML发送到浏览器的想法.您可能会发现prepareAndRender()辅助函数更有趣,但最终它用于$this->renderLayout()创建输出html(这里$this是控制器).


第二部分

我认为您需要专注于代码中的行:

    echo $this->getLayout()->createBlock('ajax/product')->setTemplate('mymodule_ajax/product.phtml')->toHtml();
Run Code Online (Sandbox Code Playgroud)

并将其更改为

    echo $this->getLayout()->createBlock('mymodule_ajax/product')->setTemplate('mymodule_ajax/product.phtml')->toHtml();
Run Code Online (Sandbox Code Playgroud)

或者,在您的模块的config.xml文件中添加如下内容:(我认为这是您需要的答案)

<config>
  <global>
        <!-- ... -->

        <blocks>
            <ajax>
                <class>MyModule_Ajax_Block</class>
            </ajax>
        </blocks>

        <!-- ... -->
  </global>
</config>
Run Code Online (Sandbox Code Playgroud)

这样Magento才能理解这createBlock('ajax/product')意味着MyModule_Ajax_Block_Product而不是Mage_Ajax_Block_Product.

我还建议你MyModule改为Mymodule全程,以便中间没有大写字母.因为

$this->getLayout()->createBlock('mymodule_ajax/product')
Run Code Online (Sandbox Code Playgroud)

好了,我不明白的细节,但一般的Magento将mymodule成为MymoduleMyModule

那有意义吗?