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


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입니다.

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

또한 아래에 선언 된 구성 요소를 확인하면 해당 구성 요소가 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.