Magento 2:コントローラーアクションから「表示」に変数を渡す


12

Magento 1で、コントローラーアクションから「ビュー」にデータを渡す場合(レイアウトのブロックなど)

  1. 経由でグローバルレジストリに値/オブジェクトを追加します Mage::register

  2. 実行後にブロックオブジェクトを直接フェッチし、フェッチしたブロックオブジェクトにデータプロパティを設定します loadLayout

  3. phtmlファイル内のブロックオブジェクトのメソッドを呼び出し、ブロックオブジェクトにモデル/データベースレイヤーを使用して、コントローラーアクションで以前に保存されたデータを読み取らせる

ブロックオブジェクトメソッドを使用してデータベースから読み取ることは、Magento 2でも引き続き機能するようです。これは、特定の種類の操作に適しています。しかしながら、

  1. Magento 2にはグローバルレジストリがありません(またはありますか?)

  2. レイアウトシステムは、ファクトリを介してページオブジェクトを作成することで機能するようになりました。Magento1と同じ方法でブロック参照を取得することはできません。

Magento 2では、コントローラーアクションからビューに直接データを渡すことはできますか?それとも、これはMagentoの勇敢な新しいDesign Pattern™の世界のパターンでもありますか?これがあまりにも直接的なパターンである場合、テンプレートに表示したい計算された情報があるが、その情報をステートフルシステムに保存したくない場合(つまり、データベース)

私はこれを自分で一緒にハックするいくつかの異なる方法を考えることができますが、Magento 2 どのようにあなたにそれを望んでいるかに興味があります。

:このようなものを使用して、コントローラーアクションでブロックインスタンスをフェッチすることが可能であることを認識しています

$resultPage = $this->resultPageFactory->create();    
$block = $resultPage->getLayout()->getBlock('catalog.wysiwyg.js');        

var_dump(spl_object_hash($block));

Magento 2コアコードはこれを頻繁に行います。しかしながら-ブロックオブジェクトがコントローラオブジェクトにフェッチと思わに利用可能であるとは異なるオブジェクトphtmlのいずれかを介してテンプレート$thisまたは$block(前者($this後(一方、実際にテンプレートを描画オブジェクトであると思われる)$block)があるように思われますMagento Blockタイプのインスタンス)。

#File: path/to/template.phtml
var_dump(spl_object_hash($block));
var_dump(spl_object_hash($this));

コントローラーアクションメソッドにデータを設定すると、phtmlテンプレートでデータが利用できなくなり、spl_object_hash上記の結果を比較すると、3つの異なるハッシュが得られるため、「あるように見えます」と言います。しかし、私はこれに十分慣れていないので、上記のエラーは他のエラーになる可能性があります。したがって、ブロックにデータを設定してテンプレートで取得できた場合は、それについて聞いてみたいです!

回答:


17

#1に関しては、Magento 1で知っているものと非常によく似たレジストリがまだ存在しています。見る:\Magento\Framework\Registry

依存性注入を経由して、あなたのコンストラクタにそれを追加し、あなたの身近な使用することができます$registry->register($key, $value)し、$registry->registry($key)店舗/アクセスデータに方法を。

まだ行っていない場合は、\ Magento \ Framework名前空間を確認することをお勧めします。以前にMageやAppからアクセスできたものの多くはまだ残っており、分割されています。

ベストプラクティスに関する限り、私はそれに答えることはできませんが、答えは、コントローラーからできるだけ多くのロジックを排除することだと思います。コアを見ることはおそらくあなたの最善策です。たとえば、お客様の住所の編集ページをご覧ください:Basic controller ; 広範なブロック -必要に応じて、アドレスIDのプルとロードを含みます。それらはブロック内で直接処理します。彼らはコントローラーでそれをしないで、それを渡します。


2
トリックは、もちろん、コアのどの部分を見て、どの部分を無視するかを知ることです:)ポインターをありがとう、有用な情報を得るために+1!
アランストーム

1
最後の段落の+1。計算値を共有する必要がある場合は、計算動作をオブジェクトに分けて、その値を必要とするブロックから呼び出します。レジストリはグローバルな可変状態であり、そこから何が得られるのか確信がないため、推奨されません。ブロックがページに存在するかどうかわからないので、アクションからのブロックの直接アドレス指定も推奨されません(レイアウトによってブロックされる可能性があります)
アントンクリル

@AntonKrilページレンダラーヘルパーはどうですか?CMSページヘルパー、製品ビューヘルパーは、HTTPリクエストからレンダリングを分離するためのものですか?
イヴァンチェプルニー

5

Controller ActionからViewに変数を渡さないでください。ブロックを使用して、変数をビューに渡します(テンプレートエンジン)。


どうして?ブロックからビューにget / postパラメーターを渡すにはどうすればよいですか?ほとんどのロジックは、それらをコントローラーからビューに渡しませんか?
LucScu

ブロック内の要求オブジェクトを使用します。レジストリを介してコントローラーからのデータ取得をブロックすると、他のコントローラーでブロックすることはできません。それは時間的結合とその悪い慣行と呼ばれます
-KAndy

$ block-> assign()を使用して、リクエストのパラメーターをコントローラーからブロックに渡します。それも悪い習慣ですか?
LucScu

ブロックがページに存在するかどうかがわからないため、アクションからのブロックの直接アドレス指定も推奨されません。
カンディ

私の場合、コントローラー、レイアウト、ブロックがコードでのみ制御されるカスタムシナリオであるため、コントローラーからブロックへのロジックパスリクエストのパラメーターであると確信しています。あなたの返信のためのThx!
-LucScu
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.