추가 / 편집 양식에 이미지 양식 요소 추가


12

관리자 목록 및 양식에 ui 구성 요소를 사용하여 Magento 2 용 CRUD 모듈을 작성 중이며 내 엔티티 중 하나에 이미지 필드가 있습니다.
그러나 나는 그것이 제대로 작동하도록 만들 수 없습니다.
작동 방식은 다음과 같습니다.
이미지가 추가되지 않은 추가 모드 또는 편집 모드에서는 간단한 파일 입력처럼 보일 것입니다.

파일이 업로드되면 이미지 미리보기와 그 아래에 삭제 상자가 표시됩니다.

나는이 디자인을 정확하게 찾고 있지 않습니다. 다르게 보일 수 있지만 기능은 동일합니다.

Magento 1에서는 자체 블록 렌더러를 만들어서이 작업을 수행 할 수있었습니다.

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;
    }
}

그리고 이것을 폼 블록에 추가

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

그러나 Magento 2에는 양식 블록이 없습니다
.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>

분명히이 클래스를 만들어야하지만 무엇을 확장해야합니까?
내가 아는 것은 인터페이스를 구현해야 Magento\Framework\View\Element\UiComponentInterface하지만 확장 할 수있는 것은 아무것도 없다는 것입니다.
그래서 내 진짜 질문은 : 원하는 행동을 달성하기 위해 수업을 확장 할 수 있습니까? 그렇지 않다면 어떻게이 요소 렌더러를 만들 수 있습니까?


@Marius 안녕하세요, 예를 사용하여 사용자 지정 그리드 편집 페이지에 제품 이미지를 추가하려고했지만 다음 오류가 발생했습니다. 치명적인 오류 : 'Varien_Data_Form_Element_'클래스를 찾을 수 없습니다. 146 행의 \ Abstract.php
— bestwebdevs

답변:


21

현장에 수업을 첨부하지 않고도 할 수있는 방법을 찾았습니다. 폼 요소에는 클래스가 있지만 렌더러는 아닙니다.
열은 다음과 같이 정의해야합니다.

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

또한에서 참조하는 미리보기 템플릿 파일을 만들어야했습니다 [Namespace]_[Module]/image-preview.
그것은 app/code/[Namespace]/[Module]/view/adminhtml/web/template/image-preview.html다음과 같습니다

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

이 코드는 다음과 같은 필드를 생성합니다.

이미지를 실시간으로 업로드하면 다음과 같습니다.

url 내부 의 항목 uploaderConfig은 업로드시 이미지가 게시되는 URL입니다. 그래서 나는 이것을 만들어야했다.

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

이 클래스는와 [Namespace]\[Module]\Model\ImageUploader비슷한 인스턴스를 사용합니다 \Magento\Catalog\Model\ImageUploader.

이 솔기가 작동합니다. 여전히 이미지를 DB에 저장하는 데 문제가 있지만 완전히 다른 문제입니다. 카테고리 엔티티
의 image필드를 영감으로 사용했습니다.


이미지를 업로드하고 이미지 이름을 데이터베이스에 저장 한 다음 방금 만든 레코드를 열면 이미지 필드 이외의 모든 필드가 예상대로 표시됩니다. 이미지 필드를 일반 "텍스트"필드로 변경하면 표시됩니다. 이것에 대한 아이디어가 있습니까?
— Nero

1
@네로. 특정 json 형식의 이미지 값이 필요합니다. 다음은 예입니다 당신이 적절한 JSON으로 변환하는 방법에 대한이
— 마리우스

이미지를 업로드하고 싶지는 않지만 관리자 Ui 양식으로 이미지를 표시하고 싶습니다. 실제로 프론트 엔드 양식에서 이미지를 업로드하고 관리자 UI 양식으로 표시하고 싶습니다. 어떻게해야하는지 알려주세요
— Sneha Panchal

61 번 줄의 [Namespace] [Module] \ Controller \ Adminhtml [Entity] \ Image \ upload.php에 오류가 있습니다. 답을 확인하고 업데이트하십시오.
— 프린스 파텔

@PrincePatel 오류 메시지는 무엇입니까?
— Marius

2

예, 확장해야 할 클래스는 \Magento\Ui\Component\Form\Element\AbstractElement입니다.

이 클래스 ElementInterface는 UiComponentInterface당신이 말하는 것을 확장합니다 .

또한 아래에 선언 된 구성 요소를 확인하면 해당 구성 요소가 Magento\Ui\Component\Form\Element모두 해당 클래스를 확장한다는 것을 알 수 있습니다.

이 클래스를 선택하는 이유는 render메소드가 \Magento\Backend\Block\Widget\Form\Renderer\Element이러한 클래스 유형 만 허용 하기 때문입니다 .(이것은 실제로 Magento\Framework\Data\Form\Element\AbstractElement허용되지 않는 인스턴스입니다 \Magento\Ui\Component\Form\Element\AbstractElement)


내 수업의 모습에 대한 조언이 있습니까?
— Marius

@Marius 흠 내가 알아하려고합니다, 너무 확실하지 않다
— 라파엘을 디지털 Pianism에서

1
아직 그렇게 할 필요는 없다고 생각합니다. UI 구성 요소에서 클래스를 사용하지 않고 솔루션을 찾았다 고 생각하지만 먼저 테스트해야합니다.
— Marius

: @Marius 흠 내가 잘못 생각, 나는 당신이 체크 아웃해야 이해 할수 github.com/magento/magento2-samples/tree/master/...
— 라파엘 디지털 Pianism에서
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.