Как сохранить значение переменной после подзапроса HMVC в Kohana 3.1? - PullRequest
3 голосов
/ 27 мая 2011

У меня проблема с сохранением значения переменной после подзапроса HMVC в Kohana 3.1.3.1, и я задаюсь вопросом, как лучше всего подойти / исправить это.Я думал, что дополнительные запросы в 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, но когда оно вызывается как подзапрос, мне нужно сохранить значения, установленные в контроллере поиска или в любом другом исходном контроллере.is.

Конечно, я мог бы создать оператор if в контроллере событий, чтобы обновлять только эти значения, если это основной запрос, но это, очевидно, не идеально.Должен быть способ изолировать этот подзапрос от первоначального запроса?

Что я делаю не так или как лучше решить эту проблему?

Заранее спасибо!

DM

Ответы [ 2 ]

0 голосов
/ 27 мая 2011

Я нашел проблему / решение!

Проблема в том, что на моем 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, обнаружив, был ли это начальный / основной запрос. Итак, в самом конце action_before() метода Controller_Website, где говорится:

// 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() это же свойство с новыми значениями, оно не перезаписывает его и вместо него использует исходные значения ... (Вот почему это решение работает.) Интересно.

0 голосов
/ 27 мая 2011
Request::factory()
    ->controller('events')
    ->action('filtered')
    ->execute();

Это неверно. Request::factory() вызов возвращает начальный Request экземпляр (поэтому он использует текущее значение URI). Вам нужен сгенерированный URI для вашего вызова HMVC:

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

PS. Извините, это моя ошибка. Ваш код, кажется, действителен в 3.1. В любом случае, попробуйте изменить его с помощью Request-> uri ().

...