getChildHtml()にデータを渡すか、子ブロックのメソッドを呼び出します


12

getChildHtml()呼び出しにデータを渡すことができます。その理由は、ブロックの出力は製品タイプに依存しているからです。したがって、出力を決定できるように、製品をgetChildHtmlに渡します。

私はこれを内部で行っていtemplate/checkout/cart/item/default.phtmlます。

理想的には、呼び出しは次のようになります。

echo $this->getChildHtml('child_block_name', $_item);

次に、ブロックはアイテムから製品タイプを取得し、正しい出力を表示できます。

このデータを渡すことは絶対に不可能であるgetChildHtmlため、コアブロックを書き換えずにこのタイプの動作をどのように実現できるか

私が現在持っている2つのソリューションは次のとおりです(どちらも非常に魅力的ではありません):

1-ヘルパーを作成し、ブロックとテンプレートにalaをレンダリングさせる代わりに、ヘルパーを介してhtml出力にアクセスします $this->helper('my_module')->getItemHtml($_item);

2-子ブロックにアクセスし、テンプレート内のその上でsetData:

 $this->getChild('child_name')->setData('item', $_item);
 echo $this->getChildHtml('child_name')

Magentoアーキテクチャに関しては、2番は2つの悪のうち小さいほうだと思いますが、テンプレートの内部は見苦しいです。


代わりに、子ブロックが使用するレジストリまたはセッションで「データ」を提供できますか?これをイテレーターで使用していますか?ユースケースは何ですか?
-philwinkle

希望する出力はカートアイテムの製品タイプに依存するため、ここでレジストリが役立つとは思わない。したがって、正しいデータを出力できるように、これを何らかの方法でブロックに渡す必要があります。ユースケースでは、カートアイテムに関する追加情報が表示されますが、製品タイプによって異なります
マーティウォレス

製品タイプの属性を作成できます-製品タイプに基づいて異なる属性を作成できますか?あなたではなく、独自のブロックを作成したい場合、我々は確かにその方向に助言することができますが、他のいくつかの組み込みの勝利ここで私は盗聴しようとしていることを...があるかもしれません
philwinkle

まあ、それは私がアクセスしている製品レベルの属性ですが、表示方法は製品タイプによって異なります。グループ化された製品は、単純な製品と言うよりも、同じ属性をわずかに異なってレンダリングします。出力の異なるフレーバーごとにブロックとテンプレートを使用しています
マーティウォレス

私は私が考えています私が持っているいくつかのアイデアで私の質問を更新しましたが、快適に100%はないですしている
マーティ・ウォレス

回答:


3

製品の種類に応じて、ブロックにメソッドを追加して子を取得できます(この種のロジックは、コアなどで何度か見ています)。

class ParentBlock 
{
    public function getIntuitiveNameChild($item)
    {
        return $this->getChild("intuitive_child")
                    ->setProductType($item->getProductType()) 
                    // You can also decide the product type in this setter, in the Child block.
                    ->setItem($item);
    }

    public function getIntuitiveNameChildDinamically($item)
    {
        return $this->getChild("intuitive_child_" . $item->getProductType())
                    ->setItem($item); 
    }    
}

// parent tpl
// i suggest you avoid getChildHtml(), unless you're certain that methods won't need to be called from the tpl
echo $this->getIntuitiveNameChild($_item)
          // ->someOtherMethod()
          ->toHtml();

それでも、レイアウトxmlを変更して子ブロックを追加する方法を見ると、MagentoがMage_Sales_Block_Items_Abstract::getItemHtml()およびの製品タイプに応じてマークアップをレンダリングする方法を決定することに興味があるかもしれませんMage_Checkout_Block_Cart_Abstract::getItemHtml()


この方法は、レイアウト構造をバイパスし、緊密に結合されたブロックを作成します(Magentoのすべてのように...)
ビクターシュレーダー

12

foreachループ内に子ブロックを表示している場合、上記のソリューションは機能しません。

そのためには、次のコードを使用する必要があります。

<?php
foreach ($blocks as $block) {
    $this->getChild("child.block")->setData("my_data", $any_data);
    echo $this->getChildHtml('child.block', false);
}
?>

child.blockでは$this->getMyData()、データの取得に使用でき ます。この戦略を使用すると、子ブロックは常に親から最新のデータを取得します。

の2番目のパラメーターはgetChildHtml()です$useCache。falseに設定すると、最初の出力がキャッシュされなくなり、子が再びレンダリングされます。


4

データを受信できるブロックはウィジェットと呼ばれます。ただし、これは(のプロパティに基づいて)複数のブロック定義を介して実行できます$_item

Magentoは、メソッドの短いコードに基づいて支払い方法ブロックをロードすることにより、コアで非常によく似た処理を行います。

<dd>
    <?php echo $this->getChildHtml('payment.method.'.$_code) ?>
</dd>

この擬似コードでも同じことができます。

if($type = $_item->getTypeId()){
    $this->getChildHtml('my.block.' . $type);
}

-必要になることすべては、各製品の種類ごとに異なるブロックタイプを持っているだろうbundlesimpleconfigurablevirtualgrouped。それほど悪くない、本当に。

本当にウィジェットを使用したい場合-編集した質問の2番目のアイデアの効果になります。

<?php
echo $this->getLayout()->createBlock('yourcompany/widget_class')->setType($_item->getTypeId())->toHtml();

おそらくこの答えの範囲外のウィジェットを作成します-しかし、それほど難しくはなく、CMSブロックに再利用できるという利点がありますが、ユースケースでは適用できないと思います。

ウィジェットの作成の詳細については:

http://www.magentocommerce.com/knowledge-base/entry/tutorial-creating-a-magento-widget-part-1


私はこれがこれに対する良いアプローチであると確信しているわけではなく、答えを受け入れていません。
マーティウォレス

1
ウィジェットブロックのみがデータを受信できますか?どういう意味ですか?すべてのブロックがデータを受信できます。ウィジェットは、 Magentoの面で異なるものです。
nevvermind

私は彼らができないと言ったことはありません。定義上、ウィジェットは条件付きで何かを表示するためにデータ入力を必要とします。
フィルウィンクル

0

のためにMagento 2、使用できます

<?php
foreach ($blocks as $block) {
    $block->getChildBlock("child.block")->setData("my_data", $any_data);
    echo $block->getChildHtml('child.block', false);
}
?>

データを取得するには、

$block->getMyData();

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.