开发者

CakePHP AJAX Layout

I'm working with a CakePHP application and jQuery Mobile. In the CakePHP application, RequestHandler is turned on, now, jQuery Mobile makes all of it's requests as ajax requests but requires a full page not 开发者_如何学JAVAjust what is in my view but the full layout to.

I need requesthandler and I've tried to set a layout, force a render, turn off autolayout, nothing works, cake only returns the contents of my view.

I'd really love to know what's going on here.


If anyone is interested I found a solution to this, I found out that when you have RequestHandler on and make a Ajax request, it doesn't matter what you do, RequestHandler then decides that your layout is 'ajax' via call backs, this probably applies for all non-html request types, like json and text.

I had to set

$this->RequestHandler->enabled = false; 

It really needs to be set in beforeFilter() as well, latter in the call chain and it appears to not work.

So my code ended up as:

class AppController extends Controller {
  var $components = array('RequestHandler');
  function beforeFilter() {
    if ($this->RequestHandler->isMobile()) {
      $this->RequestHandler->enabled = false
      //set special mobile rules here
    }
  }
}


I was having the same problem with a CakePHP 1.3 app that is using jQueryMobile to build mobile-friendly views. I'll try to lay it out for future searches.

When I switched on $.mobile.ajaxEnabled = true; for jQM's nice Ajax-based navigation all the linked pages showed undefined instead of the page content. The Ajax nav requires that the linked page have the proper structure, like so:

<div data-role="page">
    <div data-role="header">
        <h1>Page Title</h1>
    </div><!-- /header -->
    <div data-role="content">   
        <p>Page content goes here.</p>      
    </div><!-- /content -->
    <div data-role="footer">
        <h4>Page Footer</h4>
    </div><!-- /footer -->
</div><!-- /page -->

This markup was coming from two places for my app, though: my default mobile layout had the <html>, <body> and the page and footer divs. Each view had a header and content div.

The problem arose because Cake's RequestHandler wanted to set the layout to ajax for all Ajax requests. It does this somewhere after beforeFilter(), which caused it to ignore a declared layout there (which Luke mentions).

The ajax layout is empty, unlike my default layout--it doesn't have <html> and other markup because it assumes (rightly) that you only want partial markup that will be inserted into a page by Ajax. The jQuery Ajax-based navigation does want to see the full markup though, and when it didn't receive a well-formed page when making the Ajax request it had no page to display.

So the question became, "How do I make RequestHandler use my default mobile layout for mobile page requests?" I wasn't satisfied with Luke's solution above of disabling RequestHandler completely for mobile. Luckily I found a post from May '11 with the same problem and a better solution:

Finally sorted it! I was checking to see whether a mobile device was requesting the page using $this->RequestHandler->isMobile(), but had placed it in the beforeFilter() function. Moving this to the beforeRender() function in the app_controller.php file fixed the problem. http://cakephp.1045679.n5.nabble.com/Jquery-Mobile-and-CakePHP-1-3-td4422871.html

So my code ended up something like this in AppController:

function beforeRender() {
    if ($this->RequestHandler->isMobile()) {
        $this->layout = 'm_default';
    }
}

I hope that helps someone out there.


Just set $this->layout = 'default'; in your controller, and it will use the default layout.

Or maybe you could make a header and footer element to put in your ajax and default layouts.


I was new to CakePHP and started with Version 2 several weeks ago.

So far I also keep the beforeFilter untouched to identifier isMobile() and finally use mobile-views within a Themed-Folder. Therefore I dont use subfolders for mobile-views within the default desktop-views. After adding this->layout in the condition it seems that I got rid off the undefined which appeared only via some actions links.

public function beforeRender() {
    if($this->RequestHandler->isMobile()) {
        $this->theme = 'Mobile';
        $this->layout = 'default';
    }
}


The best sollution I think is to configure the request handler in before filter after the mobile browser was detected in your app controller:

public function beforeRender() {
  if($this->RequestHandler->isMobile()) {
      $this->theme = 'Mobile';//set your theme
      $this->RequestHandler->ajaxLayout = 'public';//this does the trick, set your mobile layout, $this->layout is simply ignored or overwritten by the component
  }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜