将图像表单元素添加到添加/编辑表单


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,您好,我尝试使用您的示例在自己的自定义网格编辑页面中添加产品图像,但出现此错误:致命错误:... \ lib \ Varien \ Data \ Form中找不到类'Varien_Data_Form_Element_' \ Abstract.php,第146行
bestwebdevs,

Answers:


21

我找到了一种无需在字段上附加类的方法。我的意思是有一个附加到form元素的类,但不作为渲染器。
该列应定义为:

<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是上传图片后将其发布到的网址。所以我还需要创建这个:

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

这可以正常工作。我仍然很难在数据库中保存图像,但这是一个完全不同的问题。
image将类别实体的领域用作灵感


我可以成功上传图像并将图像名称保存到数据库中,然后在打开刚创建的记录时,除图像字段以外的所有其他字段均按预期显示。当我将图像字段更改为普通的“文本”字段时,它将显示出来。您对此有任何想法吗?
Nero

1
@Nero。您需要某种json格式的图片值。这是一个有关如何将其转换为正确的json的
Marius

我不想上传图像,但我想以admin Ui形式显示图像。实际上,我是从前端表单中上传图像并想以admin ui形式显示图像。所以请帮助我该怎么做
Sneha Panchal

行号61的[名称空间] [模块] \ Controller \ Adminhtml [实体] \ Image \ upload.php中存在错误,请检查并更新答案。
帕特尔王子(Prince Patel)

@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 hmmm我不太确定,我会尝试找出
答案

1
我认为您不需要这样做。我想我找到了一种解决方案,而没有在ui组件中使用类,但是我需要先进行测试。
马里斯(Marius)

@Marius哦,我倒觉得我错了,我想你应该检查出:github.com/magento/magento2-samples/tree/master/...
拉斐尔在数码钢琴艺术
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.