2011-05-27 23 views
3

我在保存Kohana 3.1.3.1中的HMVC子请求之后保留一个变量的值时遇到了问题,并且想知道如何最好地处理/修复它。我认为,在Kohana的其他请求被相互隔离,但它似乎并没有这样的情况?如何在Kohana 3.1中的HMVC子请求后保留变量的值?

首先,我创建了一个控制器,扩展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()很长,我已经设置了一对使用这种方法输出多个事件页面的路线(l ike按年份,月份,地点,城市等过滤事件),因此在我的搜索控制器中复制此方法没有任何意义。因此需要HMVC请求。当被过滤的动作被调用为主/初始请求时,在$page_info中设置值是有意义的,但是当它被称为子请求时,我需要保留在搜索控制器中设置的值,或者无论初始控制器是什么。

当然,如果是主要请求,我可以在事件控制器中创建一个if语句来更新这些值,但显然这并不理想。必须有办法使这个子请求运行与初始请求隔离吗?

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

提前致谢!

DM

+0

澄清一下,可以肯定的是:在最初的请求中,你回显了一些变量,而且它的值似乎已经通过调用HMVC请求而改变了? – Tadeck 2011-05-27 00:53:47

+0

@Tadeck - 是的,变量只在模板视图中回显(例如页面标题)。一旦运行HMVC请求,例如'$ this-> page_info-> page_title'就会停留在事件控制器中设置的任何值,并且我无法在搜索控制器中更改它,即使我尝试在其中更改它搜索控制器的'after()'方法... – 2011-05-27 01:08:17

回答

0

我发现问题/解决方案!

的问题是,在我的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 - 这实际上是工作作为它应该通过让你改变了这个变量的值事实上... (确实非常整洁的功能。)

解决方法是通过检测它是否为初始/ m来强制模板仅使用原始的page_info ain请求。所以在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值,而不会影响模板中使用的值。那么,如果你将一个属性分配给一个视图,然后尝试使用新值对同一个属性进行尝试,那么它就不会覆盖它并使用原来的值来代替...... (这就是解决方案的原因。 )有趣。

0
Request::factory() 
    ->controller('events') 
    ->action('filtered') 
    ->execute(); 

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

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

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