ExtJS、store、HasMany-BelongsTo和更新过程:如何?

ExtJS、store、HasMany-BelongsTo和更新过程:如何?,extjs,extjs4,Extjs,Extjs4,我有两个数据模型:Writer.attributevaleur和Writer.Produit Writer.Produit与Writer.attributevaleur有很多关系 因此,定义如下: Ext.define('Writer.AttributValeur', { extend: 'Ext.data.Model', fields: [{ name: 'id', type: 'int', useNull

我有两个数据模型:
Writer.attributevaleur
Writer.Produit

Writer.Produit
Writer.attributevaleur
有很多关系

因此,定义如下:

Ext.define('Writer.AttributValeur', {
    extend: 'Ext.data.Model',
    fields: [{
            name: 'id',
            type: 'int',
            useNull: true
        },  
        'description',
        'val'
    ],  
    belongsTo: 'Writer.Produit'
});

Ext.define('Writer.Produit', {
    extend: 'Ext.data.Model',
    fields: [{
            name: 'id',
            type: 'int',
            useNull: true
        },  
        'titre',
        'description'
    ],
    hasMany: {
        model: 'Writer.AttributValeur',
        name: 'attributs'
    }   
});

var store = Ext.create('Ext.data.Store', {
    model: 'Writer.Produit',
    autoLoad: true,
    autoSync: true,
    proxy: {
        type: 'ajax',
        api: {
            read: 'json/liste_view/',
            create:  'json/item/?mode=create',
            update:  'json/item/?mode=update',
            destroy: 'json/item/?mode=destroy'
        },
        reader: {
            type: 'json',
            successProperty: 'success',
            root: 'data',
            messageProperty: 'message'
        },
        writer: {
            type: 'json',
            writeAllFields: true,
            root: 'data'
        }
    }
});
form.getRecord().attributs().add(newrecord);
现在,当我阅读该文件,询问“Produits”时,有一个AJAX答案非常有效:

在每一行中,都有许多
Writer.attributevaleur
(我把它们化名为“attributes”,见图):

问题是当我在这个“
attributes
”字段中插入
Writer.attributevaleur
时,如下所示:

Ext.define('Writer.AttributValeur', {
    extend: 'Ext.data.Model',
    fields: [{
            name: 'id',
            type: 'int',
            useNull: true
        },  
        'description',
        'val'
    ],  
    belongsTo: 'Writer.Produit'
});

Ext.define('Writer.Produit', {
    extend: 'Ext.data.Model',
    fields: [{
            name: 'id',
            type: 'int',
            useNull: true
        },  
        'titre',
        'description'
    ],
    hasMany: {
        model: 'Writer.AttributValeur',
        name: 'attributs'
    }   
});

var store = Ext.create('Ext.data.Store', {
    model: 'Writer.Produit',
    autoLoad: true,
    autoSync: true,
    proxy: {
        type: 'ajax',
        api: {
            read: 'json/liste_view/',
            create:  'json/item/?mode=create',
            update:  'json/item/?mode=update',
            destroy: 'json/item/?mode=destroy'
        },
        reader: {
            type: 'json',
            successProperty: 'success',
            root: 'data',
            messageProperty: 'message'
        },
        writer: {
            type: 'json',
            writeAllFields: true,
            root: 'data'
        }
    }
});
form.getRecord().attributs().add(newrecord);
它工作得很好,但当我调用
store.sync()
时,什么也没发生。因此,我用手将记录标记为
脏的

form.getRecord().attributs().add(newrecord);
form.getRecord().setDirty();
form.getRecord().store.sync();
现在它已发送,但
属性
未发送!见:


如何将其“添加”到更新过程中?

来自sencha文档-看起来您需要在
form.getRecord().attributes()
上调用sync,而不是在主记录上。你能试试吗


据我所知,该功能在4.0x中不受支持,也不在4.1的功能路径上。 有人试图解决问题,但是,请参见以下线程:


还有另一种有趣的表单方法:Jamie Sutherland所著

Ext.data.writer.Json.override({
  {*/*
     * This function overrides the default implementation of
     * json writer. Any hasMany relationships will be submitted
     * as nested objects
     */*}
    getRecordData: function(record) {
        var me = this, i, association, childStore, data = {}; 
        data = me.callParent([record]);

        /* Iterate over all the hasMany associations */
        for (i = 0; i < record.associations.length; i++) {
            association = record.associations.get(i);
            if (association.type == 'hasMany')  {
                data[association.name] = []; 
                childStore = eval('record.'+association.name+'()');

                //Iterate over all the children in the current association
                childStore.each(function(childRecord) {

                    //Recursively get the record data for children (depth first)
                    var childData = this.getRecordData.call(this, childRecord);
                    if (childRecord.dirty | childRecord.phantom | (childData != null)){
                        data[association.name].push(childData);
                        record.setDirty();
                    }   
                }, me);
            }   
        }   
        return data;
    }   
}); 
当我添加一个嵌套记录时,下面是我如何使用
attributes
实现这一点的,这是一种单一的关联(参见我的问题)。需要注意的是,我设置了脏所有嵌套的记录,以确保它们已发送:

var rec = this.formDst.getRecord(),
    atts = rec.attributs();
atts.add(sel);
for (var i = 0; i <atts.data.items.length; i++) {
    atts.data.items[i].setDirty();
};
rec.setDirty();
rec.store.sync();
this.close();
var rec=this.formDst.getRecord(),
atts=记录属性();
附件添加(sel);

对于(var i=0;i我喜欢简单的解决方案,因此我还添加了以下内容以支持:

Ext.data.writer.Json.override({
getRecordData:function (record) {

    var me = this, i, association, childStore, data = {};
    data = me.callParent([record]);

    /* Iterate over all the hasMany associations */
    for (i = 0; i < record.associations.length; i++) {

        association = record.associations.get(i);
        if (association.type == 'hasMany') {
            data[association.name] = [];
            childStore = eval('record.' + association.name + '()');

            //Iterate over all the children in the current association
            childStore.each(function (childRecord) {

                //Recursively get the record data for children (depth first)
                var childData = this.getRecordData.call(this, childRecord);
                if (childRecord.dirty | childRecord.phantom | (childData != null)) {
                    data[association.name].push(childData);
                    record.setDirty();
                }
            }, me);
        }

        if(association.type == 'belongsTo') {

            // we need ucfirst
            var method = 'get' + association.name.charAt(0).toUpperCase() + association.name.slice(1);
            var childRecord = eval('record.' + method + '()');
            var childData = this.getRecordData.call(this, childRecord);

            if (childRecord.dirty | childRecord.phantom | (childData != null)) {
                data[association.name] = childData;
                record.setDirty();
            }

        }

    }
    return data;
}
Ext.data.writer.Json.override({
getRecordData:函数(记录){
var me=this,i,association,childStore,data={};
data=me.callParent([record]);
/*迭代所有的hasMany关联*/
对于(i=0;i

})

我已经试过了:什么都没有发生。我试着把
setDirty()
放在所有地方,但总是有异常(=坏地方),除了
this.formDst.getRecord().setDirty();
。我在这里发现了一个非常有趣的问题,答案很好。碰巧没有做任何“自动”保存的事情嵌套关联,不符合逻辑:可以“自动”加载嵌套关联,但不能“自动”保存它们……不适用于ExtJs4.0:
uncaughtTypeError:Object[Object]没有方法“getData”
。该死的x 2!不适用于ExtJS 4.1:
Uncaught TypeError:无法读取未定义的
的属性“persist”(我试图使用
Ext.data.writer.DeepJson
类添加最新的解决方案。不起作用。我将尝试使用其他示例,可能会起作用,只有天知道……如果这是个bug(省略)来自标准ExtJs逻辑-我建议通过包含此附加属性来扩展standard writer。没错。这就是为什么我发布了一个可以帮助社区的解决方案。无论如何,如果嵌套“修改”记录不是与主记录一起发布的,它打破了整个KISS+DRY原则。我同意,我一直认为4.0中的模型关联最多是半成品。你很清楚它是否有效吗?你能注意到在Sencha线程上发布的解决方案中遗漏的部分吗?下面是另一个有趣的表单方法:我一直在使用wo7月20日在它上面工作,所以我编辑了这个解决方案,因为我的另一个解决方案在插入新记录时不起作用。现在(1)一切正常(2)它调用父函数(=sencha最初的
getRecordData()
函数),这更安全、更智能,并且从长远来看可能保持兼容(3)它要短得多,因此更容易理解为什么我保存时.writealFields为false?我建议您将
eval('record.'+association.name+'());
更改为
record[association.name]();
谢谢,我正要将此添加到自己的文件中。