Truyền dữ liệu cho getChildHtml () hoặc gọi phương thức trên khối con


12

Tôi muốn có thể truyền dữ liệu đến cuộc gọi getChildHtml (). Lý do là, đầu ra của khối phụ thuộc vào loại sản phẩm. Vì vậy, tôi muốn chuyển sản phẩm cho getChildHtml để nó có thể quyết định đầu ra.

Tôi đang làm điều này bên trong template/checkout/cart/item/default.phtml.

Lý tưởng nhất là cuộc gọi sẽ như sau:

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

Sau đó, khối của tôi có thể lấy loại sản phẩm từ mặt hàng và hiển thị đầu ra chính xác.

Vì chắc chắn không thể truyền dữ liệu này đến getChildHtml- làm thế nào loại hành vi này có thể đạt được mà không phải viết lại khối lõi

Hai giải pháp tôi hiện đang có như sau (không hấp dẫn lắm):

1 - Tạo một trình trợ giúp và truy cập đầu ra html thông qua trình trợ giúp thay vì để một khối và mẫu kết xuất nó ala $this->helper('my_module')->getItemHtml($_item);

2 - Truy cập khối con và setData trên nó bên trong mẫu:

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

Tôi nghĩ về mặt kiến ​​trúc Magento, số 2 là ít tệ hơn của hai tệ nạn, nhưng nó trông thật xấu xí khi nhìn vào một khuôn mẫu.


Thay vào đó, bạn có thể cung cấp 'dữ liệu' trong sổ đăng ký hoặc phiên mà khối con sử dụng không? Bạn đang sử dụng điều này trong một iterator? Trường hợp sử dụng là gì?
philwinkle

Tôi không nghĩ rằng đăng ký sẽ giúp ở đây vì đầu ra mong muốn phụ thuộc vào loại sản phẩm giỏ hàng. Vì vậy, điều này phải được chuyển đến khối theo một cách nào đó để dữ liệu chính xác có thể được xuất ra. Ca sử dụng được hiển thị một số thông tin bổ sung về mặt hàng giỏ hàng, nhưng tùy thuộc vào loại sản phẩm
Marty Wallace

Bạn có thể tạo các thuộc tính loại sản phẩm - có lẽ bạn tạo các thuộc tính khác nhau dựa trên các loại sản phẩm? Nếu bạn muốn tạo khối riêng của mình, chúng tôi chắc chắn có thể tư vấn theo hướng đó nhưng có thể có một số chiến thắng tích hợp khác ở đây mà tôi đang cố gắng đánh hơi ...
philwinkle

Vâng, đó là một thuộc tính cấp độ sản phẩm mà tôi đang truy cập, nhưng cách nó được hiển thị tùy thuộc vào loại sản phẩm. Một sản phẩm được nhóm sẽ hiển thị cùng một thuộc tính khác một chút so với nói một sản phẩm đơn giản. Tôi đang sử dụng một khối và mẫu cho mỗi hương vị đầu ra khác nhau
Marty Wallace

Tôi đã cập nhật câu hỏi của mình với một số ý tưởng mà tôi đang suy nghĩ nhưng tôi không thoải mái 100% với
Marty Wallace

Câu trả lời:


3

Bạn có thể thêm một phương thức trên khối cha để tìm nạp con tùy thuộc vào loại sản phẩm (Tôi đã thấy loại logic này một vài lần trong lõi hoặc một cái gì đó tương tự):

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

Tuy nhiên, xem cách bạn sửa đổi bố cục xml để thêm các khối con, bạn có thể quan tâm đến cách Magento quyết định làm việc với kết xuất đánh dấu tùy thuộc vào loại sản phẩm trong Mage_Sales_Block_Items_Abstract::getItemHtml()Mage_Checkout_Block_Cart_Abstract::getItemHtml().


Phương pháp này bỏ qua cấu trúc bố cục và tạo ra các khối được ghép chặt chẽ (như mọi thứ trong Magento ...)
Victor Schröder

12

Giải pháp trên sẽ không hoạt động nếu bạn đang hiển thị khối con trong foreachvòng lặp.

Cho rằng bạn cần sử dụng mã sau đây:

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

Trong child.block bạn có thể sử dụng $this->getMyData()để lấy dữ liệu. Sử dụng chiến lược này, khối con sẽ luôn nhận được dữ liệu mới nhất từ ​​cha mẹ.

Tham số thứ hai của getChildHtml()$useCache. Đặt nó thành false sẽ ngăn đầu ra đầu tiên được lưu vào bộ nhớ cache và buộc hiển thị lại con.


4

Một khối có thể nhận dữ liệu được gọi là một widget ; mặc dù điều này có thể được thực hiện thông qua nhiều định nghĩa khối (dựa trên các thuộc tính của $_item).

Magento thực hiện một cái gì đó rất giống trong lõi bằng cách tải khối phương thức thanh toán dựa trên mã ngắn của phương thức:

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

Bạn có thể làm tương tự với mã giả này:

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

Tất cả những gì sẽ yêu cầu sẽ có một loại khối khác nhau đối với từng loại sản phẩm - bundle, simple, configurable,virtual , grouped. Không tệ lắm, thật đấy.

Nếu bạn thực sự muốn sử dụng một widget - nó sẽ là một cái gì đó ảnh hưởng đến ý tưởng thứ hai của bạn trong câu hỏi được chỉnh sửa của bạn:

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

Tạo một tiện ích có thể nằm ngoài phạm vi của câu trả lời này - nhưng nó không quá khó và có lợi thế là có thể lại cho các khối CMS, mặc dù trong trường hợp sử dụng của bạn, tôi không nghĩ rằng nó có thể áp dụng được.

Để biết thêm thông tin về việc tạo một widget:

http: //www.magentoc Commerce.com/ledgeledge-base/entry/tutorial-creating-a-magento-widget-part-1


Tôi không tin chắc 100% đây là một cách tiếp cận tốt cho điều này mà tôi chưa chấp nhận câu trả lời.
Marty Wallace

1
Chỉ một khối widget có thể nhận dữ liệu? Ý anh là gì? Tất cả các khối có thể nhận dữ liệu. Một widget là một cái gì đó khác nhau trong thuật ngữ Magento.
nevvermind

Tôi chưa bao giờ nói họ không thể; Tôi đang nói, theo định nghĩa, một widget yêu cầu nhập dữ liệu để hiển thị một cái gì đó có điều kiện.
philwinkle

0

Đối với Magento 2, bạn có thể sử dụng

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

Để có được dữ liệu,

$block->getMyData();

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.