ส่งผ่านข้อมูลไปยัง getChildHtml () หรือวิธีการโทรในบล็อกย่อย


12

ฉันต้องการส่งผ่านข้อมูลไปยังการเรียกใช้ getChildHtml () เหตุผลคือผลลัพธ์ของบล็อกขึ้นอยู่กับประเภทของผลิตภัณฑ์ ดังนั้นฉันต้องการส่งผลิตภัณฑ์ไปที่ getChildHtml เพื่อให้สามารถตัดสินใจเกี่ยวกับผลลัพธ์

template/checkout/cart/item/default.phtmlฉันกำลังทำอยู่ภายในนี้

เป็นการดีที่การโทรจะมีลักษณะดังนี้:

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

จากนั้นบล็อกของฉันจะได้รับประเภทผลิตภัณฑ์จากรายการและแสดงผลลัพธ์ที่ถูกต้อง

เนื่องจากเป็นไปไม่ได้ที่จะส่งผ่านข้อมูลนี้ไปgetChildHtml- พฤติกรรมประเภทนี้สามารถทำได้โดยไม่ต้องเขียนบล็อกแกนใหม่

สองวิธีที่ฉันมีอยู่ในปัจจุบันมีดังนี้ (ไม่น่าสนใจมาก):

1 - สร้างผู้ช่วยและเข้าถึงเอาต์พุต html ผ่านตัวช่วยแทนที่จะปล่อยให้บล็อกและเทมเพลตแสดงเป็น ala $this->helper('my_module')->getItemHtml($_item);

2 - เข้าถึงบล็อกย่อยและ setData ที่อยู่ด้านในเทมเพลต:

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

ฉันคิดว่าในแง่ของสถาปัตยกรรมวีโอไอพีหมายเลข 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 เพื่อเพิ่มเด็กบล็อกคุณอาจจะสนใจในวิธีการที่วีโอไอพีจึงตัดสินใจที่จะทำงานร่วมกับมาร์กอัปการแสดงผลขึ้นอยู่กับประเภทของสินค้าในและ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การตั้งค่าเป็นเท็จจะป้องกันไม่ให้เอาต์พุตแรกถูกแคชและบังคับให้เรนเดอร์ลูกอีกครั้ง


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();

การสร้างวิดเจ็ตอาจอยู่นอกขอบเขตของคำตอบนี้ - แต่ก็ไม่ได้ยากมากและมีข้อได้เปรียบที่สามารถrepurposedสำหรับบล็อก CMS ได้ แต่สำหรับกรณีการใช้งานของคุณฉันไม่คิดว่ามันเหมาะสม

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการสร้างวิดเจ็ต:

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


ฉันไม่มั่นใจ 100% นี่เป็นวิธีการที่ดีซึ่งฉันไม่ยอมรับคำตอบ
Marty Wallace

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.