รายการ "แหล่งที่มา" ในไฟล์คอมโพเนนต์ UI คืออะไร


17

ในไฟล์การกำหนดค่า UI ส่วนประกอบของ Magento 2 คุณมักจะเห็นแอ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"มีไว้เพื่ออะไร? ฉันรับรู้ถึง UI Component mechanic ที่ใช้ XML และกำหนดค่าเป็นx-magento-initJSON

"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ได้อย่างไร

ถ้าฉันมองไปที่uiElement's initModulesวิธี

    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เป็นฟังก์ชั่น callable:

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

ถ้าthis.sourceไม่ได้เป็นฟังก์ชั่น callable ก็แทนที่ this.sourceด้วยตัวแทน UI this.providerจากรีจิสทรีใช้ อีกครั้งนี้คือแม้ว่าและไม่ได้เป็นprovider sourceดังนั้นหากแหล่งที่มาไม่ใช่ฟังก์ชั่น callable ณ จุดนั้นก็เพียงแค่โหลดผู้ให้บริการและต้นฉบับthis.sourceจะไปทางลม

this.sourceมักจะเป็นที่ว่างเปล่า แต่ในกรณีของcms_block_form, this.sourceจะ'block'เริ่มต้นด้วย เนื่องจากเป็นสตริงและไม่ใช่ฟังก์ชัน callable มันจึงถูกเขียนทับ

นอกจากนี้โปรดทราบว่า UI Component สามารถเพิ่มตรรกะบางอย่างเพื่อตั้งค่าthis.sourceให้ฟังก์ชัน callable ซึ่งอ้างอิงจากสตริงจาก 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()ฟังก์ชั่นกลับมาจากการเป็น - ไม่น่าแปลกใจ - ฟังก์ชั่น callable ด้วยเหตุนี้สิ่งนี้จึงประเมินว่าเป็นเท็จและถูกข้าม:

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() 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การประกาศก็มีการเข้าถึงโดยตรงเพื่อดำเนินการวิธีการที่มันเป็นsourcedataProvider


สรุป:แหล่งที่มาดูเหมือนจะเป็นสิ่งที่ใช้อย่างน้อยในชั้นเรียน Javascript เป็นผู้ให้บริการข้อมูล หากแหล่งที่ตั้งอยู่ในระดับ Javascript และเป็นฟังก์ชั่น callable dataProviderมันสามารถนำมาใช้ในการดำเนินการวิธีการโดยตรงบน

แม้ว่าฉันจะยังมีคำถามสองสามข้อนี้อยู่:

  • เป็นไปได้หรือไม่ที่จะใช้sourceใน XML เพื่อเชื่อมต่อคลาส dataProvider
  • มันควรจะให้บริการวัตถุประสงค์ใน XML แต่ได้รับการปฏิเสธในบางจุด?
  • มีคลาสหลักใด ๆ ที่ดูthis.source(จาก XML) และทำสิ่งที่น่าสนใจก่อนจะinitModules()ถูกเรียกใช้หรือไม่

1
+1 สำหรับข้อมูลที่เป็นประโยชน์ แต่จบลงด้วยคำถามเดียวกับที่ฉันมี - sourceกำลังทำอะไรอยู่ในไฟล์ XML เหล่านั้น :)
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>

getData()วิธีการในdataproviderชั้นจะกลับอาร์เรย์ด้วยปุ่ม 'ลูกค้า' และ 'ที่อยู่' และเขตข้อมูลที่สอดคล้องกันในสนามชุดจะถูกแมปจากมัน ภาพหน้าจอแสดงผลของgetData()วิธีการ

เอาต์พุตของเมธอด getData () ของคลาส DataProvider

หลังจากนั้นเมื่อ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 มีคีย์ชื่อลูกค้าและคีย์นั้นใช้ชื่อชื่อเป็น<item name="sourceโหนดโดยบังเอิญ อย่างไรก็ตามฉันไม่เห็นรหัส PHP ใด ๆ ที่อ้างอิงข้อมูลในโหนดต้นทาง นอกจากนี้รูปแบบหน้า CMS มี<item name="source" xsi:type="string">page</item>โหนดและข้อมูลแหล่งข้อมูลของมันไม่มีpageรหัส ในที่สุดการวิจัยของฉันระบุว่ามันเป็นname="dataScope"ตัวกำหนดว่าเขตข้อมูลใดจะได้รับค่า
อลันสตอร์ม

1
ใช่คุณพูดถูกอลัน ระหว่างการดีบักฉันเห็นสิ่งเดียวกัน (เกี่ยวกับ dataScope) ขอขอบคุณสำหรับการชี้แจง. หากฉันได้อะไรเพิ่มเติมเกี่ยวกับ "แหล่งที่มา" ฉันจะโพสต์
Pankaj Bhope
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.