Поля adminhtml ui_component не заполнены

8

Я создал форму экземпляра ui_component. Поля отображаются, но не заполняются. Даже если отрендеренный JSON содержит данные, он не отображается.
Что я делаю неправильно? Каковы эффективные шаги отладки?

Вот что у меня есть. Для целей тестирования я сделал сущность совершенно минимальной (два поля: foo_idи name).

XML-код ui_component:

<?xml version="1.0" encoding="UTF-8"?>
<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <argument name="data" xsi:type="array">
        <item name="js_config" xsi:type="array">
            <item name="provider" xsi:type="string">example_foo_form.example_foo_form_data_source</item>
            <item name="deps" xsi:type="string">example_foo_form.example_foo_form_data_source</item>
        </item>
        <item name="config" xsi:type="array">
            <item name="dataScope" xsi:type="string">data</item>
            <item name="namespace" xsi:type="string">example_foo_form</item>
        </item>
        <item name="label" xsi:type="string" translate="true">Foo Information</item>
        <item name="layout" xsi:type="array">
            <item name="type" xsi:type="string">tabs</item>
            <item name="navContainerName" xsi:type="string">left</item>
        </item>
        <item name="buttons" xsi:type="array">
            <item name="save" xsi:type="string">Example\Foo\Block\Adminhtml\Foo\Edit\SaveButton</item>
        </item>
    </argument>
    <dataSource name="example_foo_form_data_source">
        <argument name="dataProvider" xsi:type="configurableObject">
            <argument name="class" xsi:type="string">Example\Foo\Model\Foo\DataProvider</argument>
            <argument name="name" xsi:type="string">example_foo_form_data_source</argument>
            <argument name="primaryFieldName" xsi:type="string">foo_id</argument>
            <argument name="requestFieldName" xsi:type="string">id</argument>
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="submit_url" xsi:type="url" path="example_foo/foo/save"/>
                </item>
            </argument>
        </argument>
        <argument name="data" xsi:type="array">
            <item name="js_config" xsi:type="array">
                <item name="component" xsi:type="string">Magento_Ui/js/form/provider</item>
            </item>
        </argument>
    </dataSource>
    <fieldset name="foo">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="label" xsi:type="string" translate="true">Foo Information</item>
            </item>
        </argument>
        <field name="foo_id">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="label" xsi:type="string" translate="true">Foo ID</item>
                    <item name="visible" xsi:type="boolean">false</item>
                    <item name="dataType" xsi:type="string">text</item>
                    <item name="formElement" xsi:type="string">input</item>
                    <item name="dataScope" xsi:type="string">foo_id</item>
                </item>
            </argument>
        </field>
        <field name="name">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="label" xsi:type="string" translate="true">Name</item>
                    <item name="visible" xsi:type="boolean">true</item>
                    <item name="dataType" xsi:type="string">text</item>
                    <item name="formElement" xsi:type="string">input</item>
                    <item name="dataScope" xsi:type="string">name</item>
                </item>
            </argument>
        </field>
    </fieldset>
</form>

DataProvider:

<?php

namespace Example\Foo\Model\Foo;

class DataProvider extends \Magento\Ui\DataProvider\AbstractDataProvider
{
    public function __construct(
        \Example\Foo\Model\ResourceModel\Foo\CollectionFactory $collectionFactory,
        $name,
        $primaryFieldName,
        $requestFieldName,
        array $meta = [],
        array $data = []
    ) {
        $this->collection = $collectionFactory->create();
        parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data);
    }

    public function getData()
    {
        $data = parent::getData();
        return array_reduce($data['items'], function ($result, array $item) {
            $result[$item['foo_id']] = $item;
            return $result;
        }, []);
    }
}

Это визуализированный JSON (довольно напечатанный для удобства чтения):

{
  "types": {
    "dataSource": {
      "component": "Magento_Ui/js/form/provider"
    },
    "input": {
      "extends": "example_foo_form"
    },
    "form.input": {
      "extends": "input"
    },
    "textarea": {
      "extends": "example_foo_form"
    },
    "form.textarea": {
      "extends": "textarea"
    },
    "fieldset": {
      "component": "Magento_Ui/js/form/components/fieldset",
      "extends": "example_foo_form"
    },
    "example_foo_form": {
      "component": "Magento_Ui/js/form/form",
      "provider": "example_foo_form.example_foo_form_data_source",
      "deps": "example_foo_form.example_foo_form_data_source"
    },
    "nav": {
      "component": "Magento_Ui/js/form/components/tab_group",
      "config": {
        "template": "ui/tab"
      },
      "extends": "example_foo_form"
    },
    "html_content": {
      "component": "Magento_Ui/js/form/components/html",
      "extends": "example_foo_form"
    },
    "tab": {
      "component": "Magento_Ui/js/form/components/area",
      "extends": "example_foo_form"
    }
  },
  "components": {
    "example_foo_form": {
      "children": {
        "sections": {
          "type": "nav",
          "config": {
            "label": "Foo Information"
          },
          "children": []
        },
        "areas": {
          "type": "example_foo_form",
          "config": {
            "namespace": "example_foo_form"
          },
          "children": {
            "foo": {
              "type": "tab",
              "dataScope": "data.foo",
              "config": {
                "label": "Foo Information"
              },
              "insertTo": {
                "example_foo_form.sections": {
                  "position": 20
                }
              },
              "children": {
                "foo": {
                  "type": "fieldset",
                  "name": "foo",
                  "children": {
                    "name": {
                      "type": "form.input",
                      "name": "name",
                      "children": [],
                      "dataScope": "name",
                      "config": {
                        "component": "Magento_Ui/js/form/element/abstract",
                        "template": "ui/form/field",
                        "label": "Name",
                        "visible": true,
                        "dataType": "text",
                        "formElement": "input",
                        "displayArea": "body"
                      }
                    }
                  },
                  "config": {
                    "label": "Foo Information",
                    "displayArea": "body"
                  }
                }
              }
            }
          }
        },
        "example_foo_form_data_source": {
          "type": "dataSource",
          "name": "example_foo_form_data_source",
          "dataScope": "example_foo_form",
          "config": {
            "data": {
              "foo_id": "1",
              "name": "test1"
            },
            "submit_url": "http://m2-example.localhost/admin/example/foo/save/key/f218ccaa2d4596ecc1f63770cd913793822e7f8489bd480ca007e3890f83a4b5/",
            "params": {
              "namespace": "example_foo_form"
            }
          }
        }
      }
    }
  }
}
Vinai
источник
Я с радостью предоставлю награду в 100 баллов за хороший ответ, как только вопрос получит право на награду,
Винай
1
Вы задаете вопрос !!! интересно :)
Амит Бера
Я считаю, что целые компоненты пользовательского интерфейса довольно сложно отлаживать (или понимать) до сих пор. Devdocs вол для вида компонента пользовательского интерфейса бесполезен для меня. Требуется усилие, чтобы не начинать разглагольствовать :) Я был бы очень благодарен за хороший ответ!
Винай
У меня похожая проблема! , Сохраняет данные в виде пользовательского интерфейса, не загруженного после успешного сохранения.
Хранилища

Ответы:

10

Глядя на ваш рендеринг JSON, это выглядит

    "example_foo_form_data_source": {
      "type": "dataSource",
      "name": "example_foo_form_data_source",
      "dataScope": "example_foo_form",
      "config": {
        "data": {
          "foo_id": "1",
          "name": "test1"
        },
        "submit_url": "http://m2-example.localhost/admin/example/foo/save/key/f218ccaa2d4596ecc1f63770cd913793822e7f8489bd480ca007e3890f83a4b5/",
        "params": {
          "namespace": "example_foo_form"
        }
      }
    }

конкретно

  "config": {
    "data": {
      "foo_id": "1",
      "name": "test1"
    },

В основных формах Magento (например, в форме клиента) обычно есть другой вложенный уровень

  "config": {
    "data": {
        "foo": {
              "foo_id": "1",
              "name": "test1"
    }
    },

fooВыше относится к вашему fieldsetимени. Это должно соответствовать ключу в массиве, который Example\Foo\Model\Foo\DataProviderвозвращает ваш класс поставщика данных ( выше).

public function getData()
{
    //...        
    return [$object_id=>['foo'=>$item_data]];
}

Вносит эти коррективы, и вам должно быть хорошо идти.

Алан Сторм
источник
Это замечательно! Это, наконец, правильно объясняет один из узлов XML :) С нетерпением ждем упомянутой вами статьи
Vinai
На что ссылается $ object_id? Можете ли вы опубликовать полную функцию getData ()?
Прия Поннусамы