Thêm một yếu tố hình thức hình ảnh vào một hình thức thêm / chỉnh sửa


12

Tôi đang xây dựng mô-đun CRUD cho Magento 2 bằng cách sử dụng các thành phần ui cho danh sách và biểu mẫu quản trị viên và một trong các thực thể của tôi có trường hình ảnh.
Nhưng tôi không thể làm cho nó hoạt động như bình thường.
Đây là cách nó nên hoạt động.
Khi ở chế độ thêm hoặc trong chế độ chỉnh sửa không có hình ảnh được tải lên, nó sẽ trông giống như một tệp nhập đơn giản.

Khi một tập tin được tải lên, nó sẽ hiển thị xem trước hình ảnh và một hộp xóa bên dưới nó.

Tôi không tìm kiếm chính xác thiết kế này. Nó có thể trông khác nhau nhưng có cùng chức năng.

Trong Magento 1 tôi đã có thể làm điều này, chỉ bằng cách tạo trình kết xuất khối của riêng tôi

class {{Namespace}}_{{Module}}_Block_Adminhtml_{{Entity}}_Helper_Image extends Varien_Data_Form_Element_Image
{
    protected function _getUrl()
    {
        $url = false;
        if ($this->getValue()) {
            $url = Mage::helper('{{namespace}}_{{module}}/{{entity}}_image')->getImageBaseUrl().$this->getValue();
        }
        return $url;
    }
}

Và thêm phần này vào khối biểu mẫu của tôi

    $fieldset->addType(
        'image',
        Mage::getConfig()->getBlockClassName('{{namespace}}_{{module}}/adminhtml_{{entity}}_helper_image')
    );

Nhưng tôi không có khối biểu mẫu trong Magento 2.
Tôi biết tôi có thể sử dụng tên lớp cho trường biểu mẫu trong tệp thành phần ui

    <field name="image" class="Class\Name\Here">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="dataType" xsi:type="string">text</item>
                <item name="label" xsi:type="string" translate="true">Resume</item>
                <item name="formElement" xsi:type="string">image</item>
                <item name="source" xsi:type="string">[entity]</item>
                <item name="dataScope" xsi:type="string">image</item>
            </item>
        </argument>
    </field>

Rõ ràng tôi phải tạo lớp này, nhưng tôi nên mở rộng cái gì?
Tất cả những gì tôi biết là tôi cần thực hiện giao diện Magento\Framework\View\Element\UiComponentInterfacenhưng tôi không tìm thấy gì tôi có thể mở rộng.
Vì vậy, câu hỏi thực sự của tôi là: Tôi có thể mở rộng một số lớp để đạt được hành vi mong muốn không? Nếu không, làm thế nào tôi có thể bắt đầu tạo trình kết xuất phần tử này?


Xin chào @Marius, tôi đã thử sử dụng ví dụ của bạn để có thể thêm hình ảnh sản phẩm vào trang chỉnh sửa lưới tùy chỉnh của mình, nhưng đã gặp lỗi này: Lỗi nghiêm trọng: Class 'Varien_Data_Form_Euity_' không tìm thấy trong ... \ lib \ Varien \ Data \ Form \ Abstract.php trên dòng 146
bestwebdevs

Câu trả lời:


21

Tôi tìm thấy một cách để làm điều đó mà không yêu cầu một lớp gắn liền với trường. Ý tôi là có một lớp gắn liền với phần tử biểu mẫu nhưng không phải là trình kết xuất.
Cột phải được định nghĩa như sau:

<field name="image">
    <argument name="data" xsi:type="array">
        <item name="config" xsi:type="array">
            <item name="dataType" xsi:type="string">string</item>
            <item name="source" xsi:type="string">[entity]</item>
            <item name="label" xsi:type="string" translate="true">Image</item>
            <item name="visible" xsi:type="boolean">true</item>
            <item name="formElement" xsi:type="string">fileUploader</item>
            <item name="elementTmpl" xsi:type="string">ui/form/element/uploader/uploader</item>
            <item name="previewTmpl" xsi:type="string">[Namespace]_[Module]/image-preview</item>
            <item name="required" xsi:type="boolean">false</item>
            <item name="uploaderConfig" xsi:type="array">
                <item name="url" xsi:type="url" path="[namespace_module]/[entity]_image/upload"/>
            </item>
        </item>
    </argument>
</field>

Tôi cũng cần phải tạo tập tin mẫu xem trước được tham chiếu bởi [Namespace]_[Module]/image-preview.
Đó là app/code/[Namespace]/[Module]/view/adminhtml/web/template/image-preview.htmlnhư thế này:

<div class="file-uploader-summary">
    <div class="file-uploader-preview">
        <a attr="href: $parent.getFilePreview($file)" target="_blank">
            <img
                class="preview-image"
                tabindex="0"
                event="load: $parent.onPreviewLoad.bind($parent)"
                attr="
                    src: $parent.getFilePreview($file),
                    alt: $file.name">
        </a>

        <div class="actions">
            <button
                type="button"
                class="action-remove"
                data-role="delete-button"
                attr="title: $t('Delete image')"
                click="$parent.removeFile.bind($parent, $file)">
                <span translate="'Delete image'"/>
            </button>
        </div>
    </div>

    <div class="file-uploader-filename" text="$file.name"/>
    <div class="file-uploader-meta">
        <text args="$file.previewWidth"/>x<text args="$file.previewHeight"/>
    </div>
</div>

Mã này sẽ tạo ra một trường như thế này:

Sau khi tải lên một hình ảnh (thời gian thực), nó trông như thế này:

Các url mục bên trong uploaderConfiglà url nơi hình ảnh được đăng tải khi tải lên. Vì vậy, tôi cũng cần phải tạo ra điều này:

namespace [Namespace]\[Module]\Controller\Adminhtml\[Entity]\Image;

use Magento\Framework\Controller\ResultFactory;

/**
 * Class Upload
 */
class Upload extends \Magento\Backend\App\Action
{
    /**
     * Image uploader
     *
     * @var \[Namespace]\[Module]\Model\ImageUploader
     */
    protected $imageUploader;

    /**
     * @param \Magento\Backend\App\Action\Context $context
     * @param \[Namespace]\[Module]\Model\ImageUploader $imageUploader
     */
    public function __construct(
        \Magento\Backend\App\Action\Context $context,
        \[Namespace]\[Module]\Model\ImageUploader $imageUploader
    ) {
        parent::__construct($context);
        $this->imageUploader = $imageUploader;
    }

    /**
     * Check admin permissions for this controller
     *
     * @return boolean
     */
    protected function _isAllowed()
    {
        return $this->_authorization->isAllowed('[Namespace]_[Module]::[entity]');
    }

    /**
     * Upload file controller action
     *
     * @return \Magento\Framework\Controller\ResultInterface
     */
    public function execute()
    {
        try {
            $result = $this->imageUploader->saveFileToTmpDir('image');

            $result['cookie'] = [
                'name' => $this->_getSession()->getName(),
                'value' => $this->_getSession()->getSessionId(),
                'lifetime' => $this->_getSession()->getCookieLifetime(),
                'path' => $this->_getSession()->getCookiePath(),
                'domain' => $this->_getSession()->getCookieDomain(),
            ];
        } catch (\Exception $e) {
            $result = ['error' => $e->getMessage(), 'errorcode' => $e->getCode()];
        }
        return $this->resultFactory->create(ResultFactory::TYPE_JSON)->setData($result);
    }
}

Lớp này sử dụng một thể [Namespace]\[Module]\Model\ImageUploaderhiện tương tự như \Magento\Catalog\Model\ImageUploader.

Đường may này để làm việc. Tôi vẫn gặp khó khăn khi lưu hình ảnh trong db nhưng đó là một vấn đề hoàn toàn khác.
Tôi đã sử dụng như nguồn cảm hứng cho các imagelĩnh vực cho các thực thể thể loại


Tôi có thể tải lên hình ảnh thành công và lưu tên hình ảnh vào cơ sở dữ liệu, sau đó khi tôi mở bản ghi tôi vừa tạo, tất cả các trường không phải là trường hình ảnh đều hiển thị như mong đợi. Khi tôi thay đổi trường hình ảnh thành trường "văn bản" bình thường, thì nó sẽ hiển thị. Bạn có bất cứ ý tưởng về điều này?
Nero

1
@Nero. Bạn cần giá trị hình ảnh trong một định dạng json nhất định. Dưới đây là một ví dụ về cách bạn có thể chuyển đổi nó thành json thích hợp
Marius

Tôi không muốn tải lên hình ảnh nhưng tôi muốn hiển thị hình ảnh trong mẫu Ui của quản trị viên. Thực tế tôi tải lên hình ảnh từ hình thức frontend và muốn hiển thị nó ở dạng quản trị ui. Làm ơn hãy giúp tôi cách làm
Sneha Panchal

Có lỗi trong [Không gian tên] [Mô-đun] \ Trình điều khiển \ adminhtml [Thực thể] \ Image \ upload.php trên dòng số 61 Vui lòng kiểm tra và cập nhật câu trả lời.
Hoàng tử Patel

@PrincePatel Thông báo lỗi là gì?
Marius

2

Có, lớp bạn nên mở rộng là \Magento\Ui\Component\Form\Element\AbstractElement .

Lớp này thực hiện cái ElementInterfacemà chính nó mở rộngUiComponentInterface mà bạn đang đề cập đến.

Trên hết, nếu bạn kiểm tra các thành phần được khai báo bên dưới Magento\Ui\Component\Form\Element bạn có thể thấy rằng tất cả chúng đều mở rộng lớp đó.

Lý do tôi chọn lớp này là vì render phương thức \Magento\Backend\Block\Widget\Form\Renderer\Elementchỉ chấp nhận loại lớp đó:(Đây thực sự là một ví dụ Magento\Framework\Data\Form\Element\AbstractElementđược chấp nhận, không phải \Magento\Ui\Component\Form\Element\AbstractElement)


Bất kỳ con trỏ về cách lớp học của tôi sẽ như thế nào?
Marius

@Marius hmmm Tôi không chắc lắm, tôi sẽ cố gắng tìm hiểu
Raphael tại Digital Pianism

1
Tôi không nghĩ bạn cần phải làm điều đó. Tôi nghĩ rằng tôi đã tìm thấy một giải pháp mà không sử dụng một lớp trong thành phần ui, nhưng tôi cần thử nghiệm trước.
Marius

@Marius hmmmm Tôi nghĩ rằng tôi đã sai, tôi nghĩ bạn nên kiểm tra xem: github.com/magento/magento2-samples/tree/master/ mẹo
Raphael tại Digital Pianism 20/05/2016
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.