3

私はzf2を初めて使用し、実験しています。ビュー ヘルパーがあり、テーブル オブジェクトにアクセスするために必要です。私のコントローラーでは、次を実行できます。

$this->getServiceLocator();

しかし、理想的には、ビュー ヘルパー内でこれを実行します。残念ながら、ビュー ヘルパーからはアクセスできないようです。module.config.php でファクトリ メソッドを構成して、コンストラクタを介して渡そうとしましたが、それを試みると、Zend はモジュールのモジュールのサービス ファクトリ メソッドから作成されたモデル オブジェクトの 1 つに tablegateway オブジェクトを渡さなくなりました。 php ファイル。これは、ファクトリ メソッドを呼び出さず、パラメーターなしでインスタンス化を実行することを選択したためと思われます。

ビュー ファクトリ メソッドが異なる名前の異なるファクトリ メソッドのセットに影響を与える理由を理解しているかどうかはわかりません。

私がやっていることの何が悪いのか誰か教えてもらえますか? 詳細を提供することはできますが、現時点では、コードベース全体を提供しない限り、どの詳細が実際に重要かは不明です。

ありがとう。

4

4 に答える 4

7

Crisp はあなたの質問に対する有効な回答を提供しますが、さらに一歩進めることをお勧めします。アプリケーション内のすべてのコードがサービス ロケーター内のすべてのサービスを変更できるため、サービス ロケーターを挿入すると、ビュー ヘルパーがフレームワークおよびサービス ロケーター パターンに緊密に結合され、脆弱になります。

依存関係を直接注入する理由があるため、依存関係のみに依存し、このアンチパターンはもう実装していません。ビュー ヘルパーが に依存していると仮定すると、ビュー ヘルパーMyModule\Model\MyTableのコンストラクターは次のようになります。

namespace MyModule;

use MyModule\Model\MyTable;
use Zend\View\Helper\AbstractHelper;

class MyViewHelper extends AbstractHelper
{
  protected $table;

  public function __construct(MyTable $table)
  {
    $this->table = $table;
  }
}

あなたが指摘したように、あなたはあなたのMyTable今を注入するだけです:

namespace MyModule;

class Module
{
  public function getViewHelperConfig()
  {
    return array(
      'factories' => array(
        'MyViewHelper' => function($sm) {
          $sm = $sm->getServiceLocator(); // $sm was the view helper's locator
          $table = $sm->get('MyModule_MyTable');

          $helper = new MyModule\View\Helper\MyHelper($table);
          return $helper;
        }
      )
    );
  }
}

ビュー ヘルパー ファクトリ内では、サービス マネージャーはビュー ヘルパーのサービス マネージャーであり、テーブルが登録されている「メイン」のサービス マネージャーではないことに注意してください (以前に書いた のブログ投稿も参照してください)。がこれ$sm->getServiceLocator()を解決します。

ビュー ファクトリ メソッドが異なる名前の異なる一連のファクトリ メソッドに影響を与える理由を理解しているかどうかはわかりません。

そうではないので、コードにバグがある可能性があります。上記がうまくいかない場合は、回答を更新できるように、サービス マネージャーの構成に関する詳細をお知らせください。

上記のアプローチの大きな利点の 1 つは、ビュー ヘルパーの単体テストが非常に簡単になることです。テーブル ゲートウェイをモックして、ビュー ヘルパーの完全な動作に集中できます。

use MyModule\View\Helper\MyHelper;

public function testHelperusesTable
{
  $mock   = $this->getMock('MyModule\Model\MyTable');
  $helper = new MyHelper($mock);

  // Test your $helper now
}
于 2013-01-06T07:48:05.890 に答える
2

Module.php のビュー ヘルパー構成からビュー ヘルパーにサービス ロケーターを挿入できます。

// Application/Module.php

public function getViewHelperConfig()
{
    return array(
        'factories' => array(
            'myViewHelper' => function ($serviceManager) {
                // Get the service locator 
                $serviceLocator = $serviceManager->getServiceLocator();
                // pass it to your helper 
                return new \Application\View\Helper\MyViewHelper($serviceLocator);
            }
        )
    );
}

あなたのビューヘルパーで

<?php
namespace Application\View\Helper;

use Zend\View\Helper\AbstractHelper,
    Zend\ServiceManager\ServiceLocatorInterface as ServiceLocator;

class MyViewHelper extends AbstractHelper
{
    protected $serviceLocator;

    public function __construct(ServiceLocator $serviceLocator)
    {
        $this->serviceLocator = $serviceLocator;
    }
}
于 2013-01-05T20:22:09.600 に答える
0

Zend Frameworkで作業している間、作業を簡単にするカスタムヘルパーが必要になることがよくあります.zf1ではヘルパーからデータベースモデルにアクセスするのは簡単でしたが、カスタムビューヘルパーで任意のテーブルのデータベースモデルにアクセスする方法に行き詰まりました.それが必要なので、ビュー内の新しい db アダプター オブジェクトを作成することによって、専門外の方法で問題を回避します。これは決して良い方法ではありませんでしたが、最近、ビュー ヘルパーでデータベース アダプターにアクセスするための非常に興味深い方法を知るようになりました。任意のテーブルで任意のクエリを実行するには、Zend F2 の方法ではなく、問題を解決するための非常にシンプルで短い方法です。

これが私のモデルの例です...

<?php

namespace Application\Model;

use Zend\Db\TableGateway\TableGateway;

class SlideImageSubTable {

    protected $tableGateway;
    public $adapter;

    public function __construct(TableGateway $tableGateway) {
        $this->tableGateway = $tableGateway;
        $this->adapter = $this->tableGateway->getAdapter();
    }

    public function fetchAll() {
        $resultSet = $this->tableGateway->select();
        return $resultSet;
    }

    public function getSlideImageSub($id) {
        $id = (int) $id;
        $rowset = $this->tableGateway->select(array('id' => $id));
        $row = $rowset->current();
        if (!$row) {
            throw new \Exception("Could not find row $id");
        }
        return $row;
    }

    public function getImageMenu($id) {
        $id = (int) $id;
        $rowset = $this->tableGateway->select(array('slide_image_id' => $id));
        $rows = array_values(iterator_to_array($rowset));
        if (!$rows) {
            throw new \Exception("Could not find row $id");
        }
        return $rows;
    }

    public function saveSlideImageSub(SlideImageSub $slideImageSub) {
        $data = array(
            'slide_image_id' => $slideImageSub->slide_image_id,
            'title' => $slideImageSub->title,
            'description' => $slideImageSub->description
        );

        $id = (int) $slideImageSub->id;
        if ($id == 0) {
            $this->tableGateway->insert($data);
        } else {
            if ($this->getSlideImageSub($id)) {
                $this->tableGateway->update($data, array('id' => $id));
            } else {
                throw new \Exception('Form id does not exist');
            }
        }
    }

    public function deleteSlideImageSub($id) {
        $this->tableGateway->delete(array('id' => $id));
    }

}

「public $adapter」パブリック変数を見てください。コンストラクターでは、$this->tableGateway->getAdapter(); を呼び出して初期化します。メソッド、getAdapter() は、ゲートウェイ オブジェクトを通じて使用できます。

次に、コントローラーアクションビューで、それを任意の変数に割り当て、その変数をビューページに渡す必要があります。このような..

public function equitiesAction() {
        $image_id = $this->params('id');
        $result = $this->getTable('SlideImageSub')->getImageMenu($image_id);
        $adapter = $this->table->adapter;
        $view = new ViewModel(array(
                    'result' => $result,
                    'adapter' => $adapter,
                ));
        return $view;
    }

ビューでは、このように「アダプター」オブジェクトをカスタムビューに渡します..

<?php echo $this->GetMenuProducts( $this->adapter); ?>

カスタム ビューでは、このデータベース アダプター オブジェクトを使用して、任意のテーブルで選択クエリを作成できます。

これが誰かの役に立てば幸いです。カスタム ビュー ヘルパーでデータベース アクセスを使用する方法を調べましたが、提供された構成方法が機能しませんでした。

ありがとう

于 2013-02-28T17:16:37.043 に答える
-1
$this->getView()->getHelperPluginManager()->getServiceLocator();
于 2014-05-02T19:27:50.930 に答える