在应用程序范围内根据标头切换渲染

时间:2014-04-25 10:58:31

标签: ajax content-type phalcon

这个问题就是一个案例。

让我们设想一个显示过滤产品列表的网站页面:

  1. 如果我在浏览器中请求/products?foo=bar,我会在布局中包含一个完整页面,该布局包含一个标题,其中包含允许更改搜索标准的表单。

  2. 如果我将foo值更改为baz并提交表单,则会动态重新加载结果(例如,使用jQuery $.load()),调用{{1}在Ajax中。

  3. 如果我在iPhone应用程序中输入相同的条件,应用程序会向服务器请求/products?foo=baz,服务器会回复json对象。

  4. 所有3个调用都引用相同的资源(“产品列表”,资源意图与 REST资源一样),但都需要不同的呈现。

    1. 在第一种情况下,我需要一个完整的HTML页面(带有布局)
    2. 在第二种情况下,我需要一个部分HTML页面(没有布局)
    3. 在第三种情况下,我需要一个简单的json响应
    4. 这个渲染开关可以由标题/products?foo=bar(带或不带布局)和X-Requested-With(html / json)触发。

      在Phalcon中,给定的示例可以实现为:

      Accept

      我如何在应用程序范围内实现此机制,而不是在每个操作中复制此行为?

1 个答案:

答案 0 :(得分:2)

最简单的方法是将数据以统一格式(如果还没有)合并到一起,并将其传递给基本控制器中的方法,以与您在示例中显示的方式完全相同的方式处理该逻辑。

abstract class AbstractController extends \Phalcon\Mvc\Controller
{

    protected function prepareResponse($data)
    {

        // JSON is identified
        if ($this->request->getBestAccept() == 'application/json')
        {
            // JSON rendering (case 3)
            $this->response->setContentType('application/json');
            $this->response->setJsonContent($data);
            $this->view->disable();
            return $this->response;
        }

        // Otherwise, defaults to HTML

        // Passing data to the view
        $this->view->setVars($data);

        // Ajax call is identified
        if ($this->request->isAjax())
        {
            // Partial rendering (case 2)
            $view->disableLevel(array(
                View::LEVEL_LAYOUT => true,
                View::LEVEL_MAIN_LAYOUT => true
            ));
        }
        // Defaults to normal rendering
        else
        {
            // Layout rendering (case 1)
        }

        return null;
    }
}

class ProductsController extends AbstractController
{

    public function indexAction()
    {
        // Build data and prepare response
        return this->prepareResponse(array(
            'products' => Products::find(array(
               'foo' => $this->request->get('foo')
            ))
        ));
    }
}   

否则,它可能有点棘手。我看到以下备选方案。

使用renderJsonrenderPartial方法扩展您的基本控制器,以处理这些逻辑位(否则默认),但在您的操作中,您仍需要检查要调用哪一个。复制...

使用路由器做一些疯狂的事情以进行不同的操作,例如indexJsonActionindexPartialAction(否则默认),具体取决于条件。但你最终会得到臃肿的控制器。

相关问题