UI 구성 요소 파일의 "소스"항목


17

Magento 2의 UI 양식 구성 요소 구성 파일에는 종종 - item와 동일한 속성이 표시 됩니다.source<item name="source" xsi:type="string">block</item>

#File: vendor/magento/module-cms/view/adminhtml/ui_component/cms_block_form.xml
<field name="title">
    <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">Block Title</item>
            <item name="formElement" xsi:type="string">input</item>
            <item name="source" xsi:type="string">block</item>
            <item name="sortOrder" xsi:type="number">20</item>
            <item name="dataScope" xsi:type="string">title</item>
            <item name="validation" xsi:type="array">
                <item name="required-entry" xsi:type="boolean">true</item>
            </item>
        </item>
    </argument>
</field>    

이 분야는 무엇입니까? 필요하지 않은 것 같아서 묻습니다 . 예를 들어이 GitHub 리포지토리의 모듈은 작동하는 UI 구성 요소 양식을 구성 하지만 이러한 name="source"항목 은 사용하지 않습니다 .

name="source"품목들이 무엇인지 아는 사람이 있습니까? XML을 가져 와서 x-magento-initJSON으로 구성하는 UI 구성 요소 메커니즘을 알고 있습니다.

"block_id": {
    "type": "form.input",
    "name": "block_id",
    "dataScope": "block_id",
    "config": {
        "component": "Magento_Ui\/js\/form\/element\/abstract",
        "template": "ui\/form\/field",
        "visible": false,
        "dataType": "text",
        "formElement": "input",
        "source": "block"
    }
},

어떤가에 공급 uiElement기반 녹아웃 뷰 모델 객체. 그러나 uiElement기반 녹아웃 뷰 모델 객체 의 중첩 트리에서 이러한 필드 수준 source필드를 사용 하는 방법은 명확하지 않습니다 .

uiElementinitModules방법을 보면

    initModules: function () {
        _.each(this.modules, function (name, property) {
            if (name) {
                this[property] = this.requestModule(name);
            }
        }, this);

        if (!_.isFunction(this.source)) {
            this.source = registry.get(this.provider);
        }

        return this;
    },

객체가 source속성을 참조하는 것을 보았습니다. 설정되지 않은 경우 provider속성을 문자열 / 키 식별자로 사용하여 객체의 레지스트리에 도달합니다 . 그것은 처럼 보인다 이러한 값 source항목이 사용되지 않습니다. 그러나 PHP 코드 또는 다른 자바 스크립트 코드에서 사용될 수 있습니다. 따라서 내 질문입니다.

답변:


7

source, 데이터 공급자, 또는해야한다. 그러나 내가 알 수 있듯이 <item name="source">XML 예제 의 노드는 측정 가능한 차이를 만들지 않으며 결과없이 제거 할 수 있습니다.

방법은 다음과 같습니다.의 initModules()메소드 에는 호출 가능한 함수 elements/element.js인지 확인 this.source합니다.

if (!_.isFunction(this.source)) {
    this.source = registry.get(this.provider);
}

경우 this.source호출 가능한 함수가 아닙니다, 그것은 우선 this.source 사용하여 레지스트리에서 UI 구성 요소와 함께 this.provider. 다시 말하지만, 이것은이다 provider하지만, 아니라 source. 따라서 소스가 해당 시점에서 호출 가능한 함수가 아닌 경우 단순히 제공자를로드하고 원본 this.source은 바람의 길을갑니다.

this.source종종 비어 있지만의 경우 cms_block_form, this.source될 것 'block'으로 시작합니다. 그것이 문자열이고 호출 가능한 함수가 아니기 때문에 단순히 재정의됩니다.

또한 UI 구성 요소 를 실행 this.source하기 전에 XML의 문자열을 기반으로 호출 가능한 함수 로 설정할 논리를 쉽게 추가 할 수 있습니다 initModules().


자, 왜이 출처가 처음에 있습니까? 왜 XML에 있는지 모르겠지만 Javascript에서 목적을 제공합니다. 예를 들어, 나는 뽑았다 grid/columns/column.js. 에서 defaults: {}다음이있다 :

modules: {
    source: '${ $.provider }'
}

다시 돌아와서 다음 elements/element.js과 같이 평가됩니다 initModules().

_.each(this.modules, function (name, property) {
    if (name) {
        this[property] = this.requestModule(name);
    }
}, this);

requestModule()방법 은 다음과 같습니다 .

requestModule: function (name) {
    var requested = this._requesetd;
    if (!requested[name]) {
        requested[name] = registry.async(name);
    }
    return requested[name];
},

async()메소드는 레지스트리에서 리턴되어 initModules()에서 지정된 특성에 지정됩니다. 이 경우 레지스트리 this.source에서 async()메소드로 설정됩니다 . 이것은 내 아무것도 일어날 것 modules:{}뿐만 아니라, source하지만, 헛간이 함께 발생하는 빛 source일부 구성 요소입니다. async()반환 된 함수는 놀랍게도 호출 가능한 함수입니다. 결과적으로 이것은 거짓으로 평가되어 건너 뜁니다.

initModules: function () {
    ...

    if (!_.isFunction(this.source)) {
        this.source = registry.get(this.provider);
    }

    return this;
}, 

돌아 가기 grid/columns/column.js, source상기 격자 정렬을 변경하는 데 사용됩니다.

exportSorting: function () {
    ...
    this.source('set', 'params.sorting', {
        field: this.index,
        direction: this.sorting
    });
},

async()메소드는 기능을 처리하지만 여기서는 set()on 메소드를 호출합니다 this.source(). 소스 또는 dataProvider은 ( grid/provider.js는) 있으며 set()메소드 가 없습니다 . element/element.js그래도 부모입니다 .

set: function (path, value) {
    var data = this.get(path),
        diffs;

    diffs = !_.isFunction(data) && !this.isTracked(path) ?
        utils.compare(data, value, path) :
        false;

    utils.nested(this, path, value);

    if (diffs) {
        this._notifyChanges(diffs);
    }

    return this;
},

개념 set()은 값을 업데이트하고 가입자에게 알리는 점에서 다소 단순합니다. 따라서를 columns.js선언 한 결과로의 source메소드를 실행할 수 있습니다 dataProvider.


결론 : 소스는 적어도 Javascript 클래스에서 데이터 제공자로 사용되는 것으로 보입니다. 소스가 Javascript 클래스에 설정되어 있고 호출 가능한 함수 인 경우 소스에서 직접 메소드를 실행하는 데 사용할 수 있습니다 dataProvider.

그래도 여전히 몇 가지 질문이 남아 있습니다.

  • sourcedataProvider 클래스를 프록시하기 위해 XML에서 사용할 수 있습니까?
  • XML에서 목적을 제공해야하지만 어느 시점에서 더 이상 사용되지 않습니까?
  • this.source(XML에서) 보고 initModules()실행 하기 전에 흥미로운 것을 수행 하는 핵심 클래스가 있습니까?

1
유용한 정보는 +1이지만 sourceXML 파일 에서 수행중인 작업 과 동일한 질문으로 끝납니다.
Alan Storm

7

이것에 대한 "소스" (신음)에 갔고이 <item name="source"/>노드들은 실제로 중복 된 것처럼 보입니다 . 또는 현재 담당 Magento 엔지니어는 자신이 중복되어 있다고 생각하므로 실제로 얻을 수있는 수준에 가깝습니다.


3

소스는 ui 구성 요소가 " DataProvider "클래스가 제공 한 데이터를 읽을 수있는 키 입니다. 여러 탭과 필드 집합이있을 때 매우 유용합니다.

예를 들어 : 참조 module-customer/view/base/ui_component/customer_form.xml

<fieldset name="customer">
    <argument name="data" xsi:type="array">
        <item name="config" xsi:type="array">
            <item name="label" xsi:type="string" translate="true">Account Information</item>
        </item>
    </argument>
    <field name="entity_id">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <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="source" xsi:type="string">customer</item>**

            </item>
        </argument>
    </field>
. 
. 
.

<fieldset name="address">
    <argument name="data" xsi:type="array">
        <item name="config" xsi:type="array">
            <item name="is_collection" xsi:type="boolean">true</item>
            <item name="label" xsi:type="string" translate="true">Addresses</item>
            <item name="removeMessage" xsi:type="string" translate="true">Are you sure you want to delete this item?</item>
        </item>
    </argument>
    <field name="parent_id">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="visible" xsi:type="boolean">false</item>
                <item name="dataType" xsi:type="string">number</item>
                <item name="formElement" xsi:type="string">input</item>

                **<item name="source" xsi:type="string">address</item>**

            </item>
        </argument>
    </field>

DataProvider 클래스 의 getData()메서드는 'customer'및 'address'키가 포함 된 배열을 반환하고 필드 집합의 해당 필드가 매핑됩니다. 스크린 샷에는 방법 의 결과가 표시됩니다 .getData()

DataProvider 클래스의 getData () 메소드 출력

이후 getDataSourceData()Magento \ Ui \ Component \ Form 의 메소드가 호출되면 위의 데이터를 처리합니다.

public function getDataSourceData()
{
    $dataSource = [];

    $id = $this->getContext()->getRequestParam($this->getContext()->getDataProvider()->getRequestFieldName(), null);
    $filter = $this->filterBuilder->setField($this->getContext()->getDataProvider()->getPrimaryFieldName())
        ->setValue($id)
        ->create();
    $this->getContext()->getDataProvider()
        ->addFilter($filter);

    $data = $this->getContext()->getDataProvider()->getData();

    if (isset($data[$id])) {
        $dataSource = [
            'data' => $data[$id]
        ];
    } elseif (isset($data['items'])) {
        foreach ($data['items'] as $item) {
            if ($item[$item['id_field_name']] == $id) {
                **$dataSource = ['data' => ['general' => $item]];**
            }
        }
    }
    return $dataSource;
}

답변 주셔서 감사합니다. 그러나 이것에 대해 확신합니까? 당신이 맞는지 잘 모르겠습니다. 예. 고객 양식에서 JSON 데이터에는 customer라는 키가 있으며 해당 키는 이름 이름을 <item name="source노드 로 동시에 사용 합니다. 그러나 소스 노드의 데이터를 참조하는 PHP 코드가 표시되지 않습니다. 또한 CMS 페이지 양식에는 <item name="source" xsi:type="string">page</item>노드가 있으며 해당 데이터 소스 데이터에는 page키 가 없습니다 . 마지막으로, 내 연구에 따르면 name="dataScope"필드가 값을 얻는 위치를 결정합니다.
Alan Storm

1
네, 맞아 Alan. 디버깅하는 동안 나는 dataScope에 대해서도 같은 것을 보았습니다. 설명 주셔서 감사합니다. "소스"에 대해 더 많은 정보를 얻으면 게시하겠습니다.
Pankaj Bhope
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.