UI घटक फ़ाइलों में "स्रोत" आइटम क्या हैं


17

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 घटक मैकेनिक के बारे में जानता हूँ जो 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एक कॉल करने योग्य कार्य है:

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

यदि this.sourceकॉल करने योग्य फ़ंक्शन नहीं है, तो यह रजिस्ट्री का उपयोग करके UI घटक के साथ ओवरराइड this.source करता है this.provider। फिर, यह है provider, हालांकि, और नहीं source। जैसे, यदि स्रोत उस बिंदु पर एक कॉल करने योग्य कार्य नहीं है, तो यह बस प्रदाता को लोड करता है और मूल this.sourceहवा का रास्ता जाता है।

this.sourceअक्सर खाली है, लेकिन के मामले में cms_block_form, के साथ शुरू this.sourceहोगा 'block'। चूँकि यह एक स्ट्रिंग है और कॉल करने योग्य कार्य नहीं है, इसलिए यह केवल ओवरराइड है।

यह भी ध्यान दें कि एक यूआई घटक आसानी से this.sourceकॉल करने योग्य फ़ंक्शन पर सेट करने के लिए XML से एक स्ट्रिंग के आधार पर आसानी से कुछ तर्क जोड़ सकता है , इससे पहले initModules()कि चलाया जाए।


अब, यह स्रोत पहले स्थान पर क्यों है? मुझे नहीं पता कि यह एक्सएमएल में क्यों है, लेकिन यह जावास्क्रिप्ट में एक उद्देश्य है। एक उदाहरण के लिए, मैंने खींच लिया 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()पर विधि 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


निष्कर्ष: स्रोत ऐसा प्रतीत होता है जो उपयोग किया जाता है, कम से कम जावास्क्रिप्ट कक्षाओं में, डेटा प्रदाता के रूप में। यदि कोई स्रोत जावास्क्रिप्ट कक्षा में सेट किया गया है, और एक कॉल करने योग्य फ़ंक्शन है, तो इसका उपयोग सीधे तरीकों को निष्पादित करने के लिए किया जा सकता है dataProvider

यह मुझे अभी भी कुछ सवालों के साथ छोड़ देता है, हालांकि:

  • क्या sourceXML में डेटापॉइडर क्लास को प्रॉक्सी करने के लिए उपयोग करना संभव है ?
  • क्या यह XML में एक उद्देश्य की सेवा करने वाला था लेकिन कुछ बिंदुओं पर पदावनत हो गया?
  • क्या कोई कोर कक्षाएं हैं जो this.sourceएक्सएमएल () से देखते हैं और initModules()चलने से पहले इसके साथ कुछ दिलचस्प करते हैं?

1
उपयोगी जानकारी के लिए +1, लेकिन मेरे पास उसी प्रश्न के साथ समाप्त होता है - sourceउन XML फ़ाइलों में क्या हो रहा है :)
एलन स्टॉर्म

7

के लिए चला गया "स्रोत" इस एक के लिए (कराहना) और ऐसा लगता है कि इन <item name="source"/>नोड्स, कर रहे हैं वास्तव में, अनावश्यक। या, वर्तमान में उनके प्रभारी मैगनेटो इंजीनियर को लगता है कि वे निरर्थक हैं, इसलिए यह सत्य के जितना निकट होगा, उतना ही हम प्राप्त करेंगे।


3

स्रोत वह कुंजी है जिसके उपयोग से यूआई घटक " डेटाप्रोइडर " वर्ग द्वारा प्रदान किए गए डेटा को पढ़ सकता है । जब कई टैब और फ़ील्ड होते हैं तो यह बहुत उपयोगी होता है।

उदाहरण के लिए: देखें 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()विधि कुंजियों को 'ग्राहक' और 'पते' के साथ लौटाएगी और फ़ील्ड-सेट में संबंधित फ़ील्ड को इससे मैप किया जाएगा। स्क्रीन-शॉट 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 डेटा के नाम का एक ग्राहक होता है, और यह कुंजी संयोग से नाम के नाम को <item name="sourceनोड के रूप में उपयोग करती है। हालाँकि, मुझे कोई भी PHP कोड नहीं दिखता है जो डेटा को स्रोत नोड में संदर्भित करता है। इसके अलावा, CMS पेज फॉर्म में एक <item name="source" xsi:type="string">page</item>नोड है और इसके डेटा स्रोत डेटा में एक pageकुंजी नहीं है । अंत में, मेरे शोध से यह संकेत मिलता है name="dataScope"कि यह निर्धारित करता है कि किसी क्षेत्र को अपने मूल्य कहां मिलते हैं
एलन स्टॉर्म

1
हाँ, आप सही हैं एलन। डिबगिंग के दौरान मैंने भी यही बात (डेटास्कोप के बारे में) देखी। स्पष्टीकरण के लिए धन्यवाद। अगर मुझे "स्रोत" के बारे में कुछ और मिलता है तो मैं पोस्ट करूंगा।
पंकज भोपे
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.