3

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
}

}

コントローラの 1 つがどのように見えるかの例を次に示します。

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
    }
}

ここで、テンプレートを使用せずに、他のコントローラーの 1 つがイベント コントローラーから出力を取得できるようにしたいと考えています。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;(テンプレートは検索コントローラーの出力にのみ含まれ、イベント コントローラーの出力には含まれないことに注意してください)、"Set in Search controller"が返されることを期待していますが、代わりに"Set in Events Controller"が返されます。

問題は、このaction_filtered()メソッドが非常に長く、このメソッドを使用していくつかのイベント ページを出力するいくつかのルートを設定したことです (年、月、会場、都市などでイベントをフィルタリングするなど) ため、意味がありません。検索コントローラーでこのメソッドを複製します。したがって、HMVC 要求が必要です。フィルタリングされたアクションがメイン/初期リクエストとして呼び出される場合、値を設定するのは理にかなっています$page_infoが、サブリクエストとして呼び出される場合は、検索コントローラーまたは初期コントローラーが何であれ、設定された値を保持する必要があります。

もちろん、イベント コントローラーで if ステートメントを作成して、それがメイン リクエストの場合にのみこれらの値を更新することもできますが、それは明らかに理想的とは言えません。このサブリクエストを最初のリクエストから分離して実行する方法が必要ですか?

私は何を間違っていますか、またはこれを解決するための最良の方法は何ですか?

前もって感謝します!

DM

4

2 に答える 2

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() の使用法で変更してみてください。

于 2011-05-27T06:41:51.800 に答える
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実際には、この変数の値を後で変更できるよう にすることで、想定どおりに機能していることです... (実際、非常に優れた機能です。)

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()、上書きされずに元の値が使用されるように見えます... (これが、このソリューションが機能する理由です。) 興味深い.

于 2011-05-27T14:17:16.657 に答える