extjs - एक्स्टजे और नेस्टेड मॉडल




extjs4 (2)

मान लीजिए मेरे पास एक वाहन है जिसका नाम वाहन है

Ext.define('AM.model.Vehicle', {
    extend: 'Ext.data.Model',
    fields: [
        {name: 'brandId',  type: 'int'}, 
        {name: 'brandName',  type: 'string'},
        {name: 'modelId',  type: 'int'}, 
        {name: 'modelName',  type: 'string'},
        {name: 'yearOfRelease',  type: 'int'}
    ]

});

जैसा कि आप देख सकते हैं, वाहन मॉडल में फ़ील्ड "brandId", "brandName", आदि हैं। उदाहरण के लिए, मैं इस मॉडल का एक उदाहरण संपादित करना चाहता हूं। मैं एक संपादन फॉर्म बनाता हूं, जिसमें कॉम्बोबॉक्स को 'ब्रांड आईडी' फ़ील्ड से जोड़ा गया है। फिर मैं इस के साथ एक मॉडल उदाहरण के लिए फार्म मूल्यों को बचाता हूँ

values = form.getValues();
record.set(values);

यह सब ठीक काम करता है, लेकिन सभी क्षेत्रों के साथ एक समस्या है जो कुछ बाहरी मॉडलों का प्रतिनिधित्व करती है: केवल आईडी का अद्यतन होता है, जबकि अन्य सभी फ़ील्ड, जो आईडी पर निर्भर करते हैं, एक ही रहते हैं।

नियमित OOP भाषा में (उदाहरण के लिए जावा), मैं एक क्लास कारबैंड बनाऊँगा और वाहन वर्ग के अंदर इस वर्ग का एक उदाहरण रखूंगा। एक्स्टजे 4 में उनके पास कई रिश्ते हैं, लेकिन उनके पास नहीं है

ऐसे नेस्टेड मॉडल के लिए एक्स्टजेएस 4 में सबसे अच्छा तरीका क्या है?


4.0। * हैन के रिश्ते का समर्थन नहीं करता है 4.1 इसका समर्थन करने के लिए है

4.0.7 के लिए मेरे पास निम्न ओवरराइड जगह है

Ext.define('HOD.overrides.Form', {}, function() {

/*
 * Implementing a nested setValues for forms with
 * arrays in them.
 */
Ext.override(Ext.form.Basic, {
    setValues: function(values, arrayField) {
        var me = this;

        function setVal(fieldId, val) {
            if (arrayField) {
                fieldId = arrayField + '.' + fieldId;
            }
            var field = me.findField(fieldId);
            if (field) {
                field.setValue(val);
                if (me.trackResetOnLoad) {
                    field.resetOriginalValue();
                }
            } else if(Ext.isObject(val)) {
                me.setValues(val, fieldId);
            }
        }

        if (Ext.isArray(values)) {
            // array of objects
            Ext.each(values, function(val) {
                setVal(val.id, val.value);
            });
        } else {
            // object hash
            Ext.iterate(values, setVal);
        }
        return this;
    },
    /**
     * Persists the values in this form into the passed {@link Ext.data.Model} object in a beginEdit/endEdit block.
     * @param {Ext.data.Model} record The record to edit
     * @return {Ext.form.Basic} this
     */
    updateRecord: function(record) {
        var values = this.getFieldValues(),
        name,
        obj = {};

        function populateObj(record, values) {
            var obj = {},
            name;

            record.fields.each(function(field) {
                name = field.name;
                if (field.model) {
                    var nestedValues = {};
                    var hasValues = false;
                    for(var v in values) {
                        if (v.indexOf('.') > 0) {
                            var parent = v.substr(0, v.indexOf('.'));
                            if (parent == field.name) {
                                var key = v.substr(v.indexOf('.') + 1);
                                nestedValues[key] = values[v];
                                hasValues = true;
                            }
                        }
                    }
                    if (hasValues) {
                        obj[name] = populateObj(Ext.create(field.model), nestedValues);
                    }
                } else if (name in values) {
                    obj[name] = values[name];
                }
            });
            return obj;
        }

        obj = populateObj(record, values);

        record.beginEdit();
        record.set(obj);
        record.endEdit();

        return this;
    }
});

यह मुझे ऐसा करने की सुविधा देता है, मेरे फॉर्म में है, मैं उन्हें ऐसे नामों से बना देता हूं जैसे कि।

// Contact details
{
    xtype: 'fieldcontainer',
    defaultType: 'textfield',
    layout: 'anchor',
    fieldDefaults: {
        anchor: '80%',
        allowBlank: true
    },
    items: [

    {
        xtype: 'textfield',
        name: 'homePhone',
        fieldLabel: 'Home phone number'
    },
    {
        xtype: 'textfield',
        name: 'mobilePhone',
        fieldLabel: 'Mobile phone number'
    }]
},
{
    xtype: 'fieldcontainer',
    defaultType: 'textfield',
    layout: 'anchor',
    fieldDefaults: {
        anchor: '80%',
        allowBlank: true
    },
    items: [
    {
        name: 'address.id',
        xtype: 'hidden'
    },
    {
        name: 'address.building',
        fieldLabel: 'Building'
    },
    {
        name: 'address.street',
        fieldLabel: 'Street'
    },
    {
        name: 'address.city',
        fieldLabel: 'City'
    },
    {
        name: 'address.county',
        fieldLabel: 'County'
    },
    {
        name: 'address.postcode',
        fieldLabel: 'Postcode'
    },
    {
        name: 'address.country',
        fieldLabel: 'Country'
    }
    ]
},
]

नोटिस नाम फ़ील्ड में जो ओवरराइड सेट वैल्यू और अपडेट रेकार्ड फॉर्म को बताता है कि इन मानों को नए मॉडल में मैप करने की जरूरत है, जिसे मॉडल में इस तरह परिभाषित किया गया है।

Ext.define('HOD.model.Employee', {
    extend: 'Ext.data.Model',
    fields: [
        // Person Class
        // Auto
        'id',
        'name',
        'homePhone',
        'mobilePhone',
        {model: 'HOD.model.Address', name: 'address'}, //Address
        {model: 'HOD.model.Contact', name: 'iceInformation'} //Person
    ]
});

Ext.define('HOD.model.Address', {
    extend: 'Ext.data.Model',
    fields: [
        'building',
        'street',
        'city',
        'county',
        'postcode',
        'country'
    ],
    belongsTo: 'Employee'
});

कोई नेस्टेड मॉडल नहीं है, हालांकि यह आपके उदाहरण से स्पष्ट नहीं है कि आप ऐसा क्यों कर रहे हैं वाहन रिकॉर्ड में आईडी और नाम दोनों को सहेजने की आवश्यकता क्यों है यदि आपके पास पहले से ही किसी अन्य डेटाबेस में उस रिश्ते हैं (मुझे लगता है कि ब्रांड शब्दकोश की तरह कुछ है जहां आप सभी जोड़े आईडी / नाम रखेंगे?)।

अद्यतन: मैं निम्नलिखित करूँगा:

  • वाहन रिकॉर्ड में केवल brand_id रखें
  • जब आपके पास कोई फ़ॉर्म होता है, तो डिक्शनरी स्टोर से मूल्यों के साथ वर्तमान कॉम्बो बॉक्स और brand_id अपडेट करें
  • जब आपके पास ग्रिड होता है - तो कॉलम के लिए कस्टम 'रेंडरर' फ़ंक्शन को परिभाषित करें और ब्रांड की दुकान से ब्रांड नाम को ब्रांड नाम दें

इस तरह के कॉलम के लिए नमूना कोड है:

{ text: 'Brand Name', dataIndex: 'brand_id', 
    renderer: function(value) {
       var rec = Ext.getStore('BrandDict').getById(value);
       return rec ? rec.get('name') : '';
}