getChildHtml ()에 데이터를 전달하거나 자식 블록의 메소드를 호출


12

getChildHtml () 호출에 데이터를 전달할 수 있기를 원합니다. 그 이유는 블록의 출력이 제품 유형에 따라 달라지기 때문입니다. 그래서 출력을 결정할 수 있도록 제품을 getChildHtml에 전달하고 싶습니다.

나는 이것을 안으로하고있다 template/checkout/cart/item/default.phtml.

이상적으로는 다음과 같이 호출됩니다.

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

그런 다음 내 블록은 항목에서 제품 유형을 가져 와서 올바른 출력을 표시 할 수 있습니다.

이 데이터를 전달할 수는 없으므로 getChildHtml코어 블록을 다시 작성하지 않고도 이러한 유형의 동작을 수행 할 수있는 방법은 무엇입니까?

현재 가지고있는 두 가지 솔루션은 다음과 같습니다 (매우 매력적이지 않음).

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 번은 두 가지 악한 것보다 적지 만 템플릿 내부는 못 생겼습니다.


자식 블록이 사용하는 레지스트리 또는 세션에서 '데이터'를 대신 제공 할 수 있습니까? 이터레이터에서 이것을 사용하고 있습니까? 사용 사례는 무엇입니까?
philwinkle

원하는 출력이 장바구니 항목 제품 유형에 따라 다르므로 레지스트리가 여기에서 도움이 될 것이라고 생각하지 않습니다. 따라서 올바른 데이터를 출력 할 수 있도록 어떤 식 으로든 블록으로 전달해야합니다. 유스 케이스는 장바구니 항목에 대한 추가 정보를 표시하지만 제품 유형에 따라 다릅니다.
Marty Wallace

제품 유형 속성을 작성할 수 있습니다. 제품 유형에 따라 다른 속성을 작성할 수 있습니까? 당신이 오히려 당신 자신의 블록을 만들고 싶다면 우리는 그 방향으로 확실히 조언 할 수 있지만 여기서 스니핑하려는 다른 내장 승리가있을 수 있습니다 ...
philwinkle

글쎄, 내가 액세스하는 제품 레벨 속성이지만 표시되는 방식은 제품 유형에 따라 다릅니다. 그룹화 된 제품은 동일한 속성을 간단한 제품과 약간 다르게 렌더링합니다. 각기 다른 풍미의 출력을 위해 블록과 템플릿을 사용하고 있습니다
Marty Wallace

나는 내가 생각하고 있지만 100 % 편안하지 않은 몇 가지 아이디어로 내 질문을 업데이트했습니다.
Marty Wallace

답변:


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의 모든 것과 같이 단단히 결합 된 블록을 생성합니다.
Victor Schröder

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()데이터를 얻는 데 사용할 수 있습니다 . 이 전략을 사용하면 자식 블록은 항상 부모로부터 최신 데이터를 가져옵니다.

의 두 번째 매개 변수는 getChildHtml()입니다 $useCache. 이 값을 false로 설정하면 첫 번째 출력이 캐시되지 않고 자식이 다시 렌더링됩니다.


4

데이터를 수신 할 수있는 블록을 위젯 이라고합니다 . 이 작업은 여러 블록 정의를 통해 수행 할 수 있습니다 (의 속성에 따라 $_item).

Magento는 메소드의 짧은 코드를 기반으로 지불 메소드 블록을로드하여 코어에서 매우 유사한 작업을 수행합니다.

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

이 의사 코드로 동일한 작업을 수행 할 수 있습니다.

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

각 제품 유형에 대해 다른 블록 타입을 가지고하는 것입니다 필요로하는 모든 - bundle, simple, configurable, virtual, grouped. 그렇게 나쁘지 않습니다.

위젯정말로 사용하려면 편집 된 질문에서 두 번째 아이디어의 효과에 영향을 미칩니다.

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


나는 이것이 내가 대답을 받아들이지 않은 이것에 대한 좋은 접근 방법이라고 100 % 확신하지 못한다.
마티 월리스

1
위젯 블록 만 데이터를 수신 할 수 있습니까? 무슨 소리 야? 모든 블록은 데이터를 수신 할 수 있습니다. 위젯은 마 젠토 측면에서 뭔가 다르다.
nevvermind

나는 그들이 할 수 없다고 결코 말하지 않았다. 정의에 따르면 위젯에는 조건부로 뭔가를 표시하기 위해 데이터 입력이 필요합니다.
philwinkle

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.