【问题标题】:How do I preserve the value of a variable after an HMVC sub-request in Kohana 3.1?如何在 Kohana 3.1 中的 HMVC 子请求后保留变量的值?
【发布时间】:2011-09-03 01:09:55
【问题描述】:

我在 Kohana 3.1.3.1 中的 HMVC 子请求后保留变量的值时遇到问题,我想知道如何最好地处理/修复它。我以为 Kohana 中的附加请求是相互隔离的,但似乎并非如此......

首先,我创建了一个控制器来扩展 Controller_Template:

abstract class Controller_Website extends Controller_Template {
public  $page_info;
public  $allow_caching;

public function before()
{
    // ... more unrelated code here ...

    // Only do this if auto_render is TRUE (default)
    if ($this->auto_render === TRUE AND $this->request->is_initial())
    {
        // Set our Page_Info to the values we just loaded from the database
        $this->page_info        = clone $this->navs[$slug];
    }

    // ... more unrelated code here ...
}

public function after()
{
    // ... more unrelated code here ...

    // For internal requests, let's just get everything except for the template
    if (! $this->request->is_initial())
    {
        $this->response->body($this->template->main_view->render());
    }

    // Only if auto_render is still TRUE (Default)
    if ($this->auto_render === TRUE AND $this->request->is_initial())
    {
        // ... more unrelated code here ...
        // ... get stuff from the database to populate the template ...

        // now render the response body
        $this->response->body($this->template->render());
    }

    // ... more unrelated code here...
    // including setting headers to disable/enable caching
}

}

下面是一个示例,其中一个控制器的外观如下:

class Controller_Events extends Controller_Website {
    public function action_filtered()
    {
        // ... do some stuff ...

        // and set some values 
        $this->page_info->page_title    = 'Set in Events controller';

        // and some more stuff including generating some output
    }
}

现在我希望我的其他控制器之一能够在没有模板的情况下从事件控制器中提取输出。 Controller_Website(上图)负责从输出中排除模板,但考虑一下:

class Controller_Search extends Controller_Website {
    public function action_index()
    {
        // ... do some stuff ...

        // now let's include the result from our events controller
        $this->template->main_view->events  = Request::factory()
                                                ->controller('events')
                                                ->action('filtered')
                                                ->execute();

        // and set some values 
        $this->page_info->page_title    = 'Set in Search controller';

        // and some more stuff including generating some output
    }
}

所以当我的模板调用echo $this->page_info->page_title; 时(请记住,我的模板只包含在搜索控制器的输出中,而不是事件控制器的输出中),我希望它返回“在搜索控制器中设置” 而是返回“在事件控制器中设置”

问题是这个action_filtered() 方法很长,我设置了几个使用这种方法输出几个事件页面的路由(比如按年、月、地点、城市等过滤事件)所以在我的搜索控制器中复制此方法没有意义。因此需要 HMVC 请求。当过滤的操作被称为主/初始请求时,在$page_info 中设置值是有意义的,但是当它被称为子请求时,我需要保留在搜索控制器中设置的值,或者任何初始控制器是。

当然,我可以在事件控制器中创建一个 if 语句,仅当它是主请求时才更新这些值,但这显然不太理想。一定有办法让这个子请求独立于初始请求运行吗?

我做错了什么,或者解决这个问题的最佳方法是什么?

提前致谢!

私信

【问题讨论】:

  • 一个澄清,只是为了确定:在初始请求中,您回显了一些变量,并且似乎通过调用 HMVC 请求更改了它的值?
  • @Tadeck - 是的,该变量只会在模板视图中回显(例如页面标题)。一旦运行 HMVC 请求,$this->page_info->page_title(例如)将保持在事件控制器中设置的任何内容,并且我无法在搜索控制器中再更改它,即使我尝试在 after() 方法中更改它搜索控制器...

标签: php templates request kohana hmvc


【解决方案1】:
Request::factory()
    ->controller('events')
    ->action('filtered')
    ->execute();

它不正确。 Request::factory() 调用返回一个 initial Request 实例(因此它使用当前 URI 值)。您需要为您的 HMVC 调用生成一个 URI:

Request::factory(Request::current()->uri(array(
    'controller' => 'events', 
    'action' => 'filtered'
)))->execute();

附言。对不起,是我的错。您的代码似乎在 3.1 中有效。无论如何,尝试使用 Request->uri() 使用来更改它。

【讨论】:

    【解决方案2】:

    我找到了问题/解决方案!

    问题是在我的 Controller_Website 中我的 action_before() 中有这个:

    // Create a new DM_Nav object to hold our page info
    // Make this page info available to all views as well
    $this->page_info = new DM_Nav;
    View::bind_global('page_info', $this->page_info);
    

    问题在于bind_global - 实际上按预期工作,让您在事后更改此变量的值... (确实是一个非常简洁的功能.)

    解决方法/解决方案是通过检测它是否是初始/主要请求来强制模板仅使用原始page_info。所以在Controller_Websiteaction_before() 方法的最后,它说:

    // Only if auto_render is still TRUE (Default)
    if ($this->auto_render === TRUE AND $this->request->is_initial())
    {
    

    我在if 语句的末尾添加了这一行:

        $this->template->page_info  = $this->page_info;
    }
    

    这一行在初始/主请求中是多余的,但这意味着任何额外的子请求仍然可以访问它们自己的page_info 值,而不会影响模板中使用的值。那么,如果您将属性分配给视图,然后尝试使用新值 bind_global() 相同的属性,它不会覆盖它而是使用原始值... (这就是为什么此解决方案有效。) 有趣。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多