【问题标题】:ExtJS 4 proxy Store don't consumes delivered dataExtJS 4 代理商店不使用交付的数据
【发布时间】:2013-03-10 16:28:17
【问题描述】:

我有两个网格,每个网格都有自己的代理存储。每个商店都绑定到同一个模型,定义如下:

Ext.define('Issue', {
    extend: 'Ext.data.Model',
    fields : [{
        name : 'updated_on',
        type : 'string'
    }, {
        name : 'done_ratio',
        type : 'int'
    }, {
        name : 'start_date',
        type : 'string'
    }, {
        name : 'subject',
        type : 'string'
    }, {
        name : 'due_date',
        type : 'string'
    }, {
        name : 'created_on',
        type : 'string'
    }, {
        name : 'description',
        type : 'string'
    }, {
        name : 'id',
        type : 'int'
    }, {
        name : 'assigned_to',
        mapping: 'assigned_to.name'
    }, {
        name: 'parked',
        mapping: 'custom_fields[9].value',
        type: 'boolean'
    }]
});

存储它们的网格和相关的容器按钮等是在一个函数中创建的。这两个函数看起来像:

var createMyPanel = function() {
        var store = new Ext.data.Store({
            /*sorters: ['gemeinde','assigned_to'],
            groupField: 'gemeinde',*///comment in when want enable grouping
            model : 'Issue',
            autoLoad: true,
            autoSync: true,
            proxy : {
                type : 'rest',
                url : '/issues.json',
                reader : {
                    type : 'json',
                    root : 'issues'
                },
                extraParams : runtime.CView.Model.getParams('my')
            }
        });
        var groupingFeature = new Ext.grid.feature.Grouping({
            groupHeaderTpl: 'Gemeinde: {name} ({rows.length})'
        });
        var searching = new Ext.ux.grid.feature.Searching({
            minChars: 3,
            mode: 'local',
            searchText: 'Suche einschränken',
            selectAllText: 'Alle Felder (ab)wählen',
            searchTip: '',
            minCharsTipText: 'Bitte mindestens 3 Zeichen eingeben...',
            width: 200
        });
        var commentBtn = new Ext.Button({
            text: 'Kommentar zum gewählten Ticket erfassen',
            disabled: true,
            ticket: null,
            margin: 5
        });
        var toGfBtn = new Ext.Button({
            text: 'an GIS-Fachstelle melden',
            disabled: true,
            ticket:null,
            margin: 5
        });
        var abbruchBtn = new Ext.Button({
            text: 'als abgebrochen melden',
            disabled: true,
            ticket:null,
            margin: 5
        });
        var parkBtn = new Ext.Button({
            text: 'Ticket zurücklegen',
            disabled: true,
            ticket:null,
            margin: 5
        });
        var journalPanel = new Ext.Panel({
            title: 'Kommentare',
            html:'',
            border: false,
            autoScroll: true,
            flex: 30,
            padding: '5 5 5 5'
        });
        var buttonPanel = new Ext.Panel({
            padding: '30 30 10 30',
            border: false,
            flex: 20,
            layout: {
                type: 'vbox',
                align: 'stretch'
            },
            items:[toGfBtn, commentBtn, abbruchBtn, parkBtn]
        });
        var contentPanel = new Ext.Panel({
            title : 'Beschreibung',
            border: false,
            html:'',
            flex: 50,
            padding: '5 5 5 5'
        });
        var southPanel = new Ext.Panel({
            padding: '0 0 5 0',
            layout: {
                type: 'hbox',
                align: 'stretch'
            },
            flex: 30,
            items:[contentPanel, journalPanel, buttonPanel]
        });

        var grid = new Ext.grid.Panel({
            store : store,
            autoScroll : true,
            flex: 70,
            columns : [{
                        text : 'Ticket-Nummer',
                        width : 100,
                        sortable : true,
                        dataIndex : 'id',
                        menuDisabled : true
                    }, {
                        text : 'Abgabe-Datum',
                        sortable : true,
                        width : 100,
                        dataIndex : 'due_date',
                        menuDisabled : true
                    }, {
                        header : 'Thema',
                        width : 200,
                        sortable : true,
                        dataIndex : 'subject',
                        renderer : function(val) {
                            return '<div style="white-space:normal !important;">'
                                    + val + '</div>';
                        },
                        menuDisabled : true
                    }, {
                        header : 'Gemeinde',
                        width : 200,
                        sortable : true,
                        dataIndex : 'gemeinde',
                        menuDisabled : true

                    }, {
                        header : 'Parzelle',
                        width : 200,
                        sortable : true,
                        dataIndex : 'parzelle',
                        menuDisabled : true

                    }, {
                        header : 'zurückgelegt',
                        width : 200,
                        sortable : true,
                        dataIndex : 'parked',
                        menuDisabled : true,
                        renderer : function(val) {
                            if(val){
                                return 'Ja';
                            }else{
                                return 'Nein';
                            }
                        },
                    },{
                        header: 'Beschreibung',
                        dataIndex: 'description',
                        hidden: true,
                        menuDisabled : true
                    }],
            bbar: ['->'],
            features: [searching/*, groupingFeature*/],//comment this in when want to group
            selModel: new Ext.selection.RowModel()
        });

        var myPanel = new Ext.Panel({
            title: 'Meine Fälle',
            padding: '0 5 0 5',
            bl_id:'my',
            layout: {
                type: 'vbox',
                align: 'stretch'
            },
            items : [grid, southPanel]
        });
        return {
            that : myPanel,
            contentPanel: contentPanel,
            grid: grid,
            store: store,
            toGfBtn:toGfBtn,
            journalPanel:journalPanel,
            commentBtn:commentBtn,
            southPanel:southPanel,
            abbruchBtn:abbruchBtn,
            parkBtn:parkBtn
        }
    };

和:

var createAllPanel = function() {
    var store = new Ext.data.Store({
        /*sorters: ['gemeinde','assigned_to'],
        groupField: 'gemeinde',*///comment in when want enable grouping
        model : 'Issue',
        autoLoad: true,
        autoSync: true,
        proxy : {
            type : 'rest',
            url : '/issues.json',
            reader : {
                type : 'json',
                root : 'issues'
            },
            extraParams : runtime.CView.Model.getParams('all')
        }
    });
    var groupingFeature = new Ext.grid.feature.Grouping({
        groupHeaderTpl: 'Gemeinde: {name} ({rows.length})'
    });
    var searching = new Ext.ux.grid.feature.Searching({
        minChars: 3,
        mode: 'local',
        searchText: 'Suche einschränken',
        selectAllText: 'Alle Felder (ab)wählen',
        searchTip: '',
        minCharsTipText: 'Bitte mindestens 3 Zeichen eingeben...',
        width: 200
    });
    var commentBtn = new Ext.Button({
        text: 'Kommentar zum gewählten Ticket erfassen',
        disabled: true,
        ticket: null,
        margin: 5
    });
    var toGfBtn = new Ext.Button({
        text: 'an GIS-Fachstelle melden',
        disabled: true,
        ticket:null,
        margin: 5
    });
    var abbruchBtn = new Ext.Button({
        text: 'als abgebrochen melden',
        disabled: true,
        ticket:null,
        margin: 5
    });
    var parkBtn = new Ext.Button({
        text: 'Ticket zurücklegen',
        disabled: true,
        ticket:null,
        margin: 5
    });
    var journalPanel = new Ext.Panel({
        title: 'Kommentare',
        html:'',
        border: false,
        autoScroll: true,
        flex: 30,
        padding: '5 5 5 5'
    });
    var buttonPanel = new Ext.Panel({
        padding: '30 30 10 30',
        border: false,
        flex: 20,
        layout: {
            type: 'vbox',
            align: 'stretch'
        },
        items:[toGfBtn, commentBtn, abbruchBtn, parkBtn]
    });
    var contentPanel = new Ext.Panel({
        title : 'Beschreibung',
        border: false,
        html:'',
        flex: 50,
        padding: '5 5 5 5'
    });
    var southPanel = new Ext.Panel({
        padding: '0 0 5 0',
        layout: {
            type: 'hbox',
            align: 'stretch'
        },
        flex: 30,
        items:[contentPanel, journalPanel, buttonPanel]
    });

    var grid = new Ext.grid.Panel({
        store : store,
        autoScroll : true,
        flex: 70,
        columns : [{
                    text : 'Ticket-Nummer',
                    width : 100,
                    sortable : true,
                    dataIndex : 'id',
                    menuDisabled : true
                }, {
                    text : 'Abgabe-Datum',
                    sortable : true,
                    width : 100,
                    dataIndex : 'due_date',
                    menuDisabled : true
                }, {
                    header : 'Thema',
                    width : 200,
                    sortable : true,
                    dataIndex : 'subject',
                    renderer : function(val) {
                        return '<div style="white-space:normal !important;">'
                                + val + '</div>';
                    },
                    menuDisabled : true
                }, {
                    header : 'Gemeinde',
                    width : 200,
                    sortable : true,
                    dataIndex : 'gemeinde',
                    menuDisabled : true

                }, {
                    header : 'Parzelle',
                    width : 200,
                    sortable : true,
                    dataIndex : 'parzelle',
                    menuDisabled : true

                }, {
                    header : 'zugewiesen an',
                    width : 200,
                    sortable : true,
                    dataIndex : 'assigned_to',
                    menuDisabled : true
                }, {
                    header : 'zurückgelegt',
                    width : 200,
                    sortable : true,
                    dataIndex : 'parked',
                    menuDisabled : true,
                    renderer : function(val) {
                        if(val){
                            return 'Ja';
                        }else{
                            return 'Nein';
                        }
                    },
                },{
                    header: 'Beschreibung',
                    dataIndex: 'description',
                    hidden: true,
                    menuDisabled : true
                }],
        bbar: ['->'],
        features: [searching/*, groupingFeature*/],//comment this in when want to group
        selModel: new Ext.selection.RowModel()
    });

    var allPanel = new Ext.Panel({
        title: 'Alle Fälle',
        padding: '0 5 0 5',
        bl_id:'all',
        layout: {
            type: 'vbox',
            align: 'stretch'
        },
        items : [grid, southPanel]
    });
    return {
        that : allPanel,
        contentPanel: contentPanel,
        grid: grid,
        store: store,
        toGfBtn:toGfBtn,
        journalPanel:journalPanel,
        commentBtn:commentBtn,
        southPanel:southPanel,
        abbruchBtn:abbruchBtn,
        parkBtn:parkBtn
    }
};

如您所见,这两个面板是相同的。当我加载页面时,请求会自动启动,导致商店将自动加载设置为 true。现在第一个商店很好地加载了数据。一切都很好,并且按预期工作。任何。第二家店没有。我通过萤火虫追踪到以下内容:

  • 商店已创建
  • 商店已正确绑定到代理
  • 调用加载函数
  • 数据请求完成
  • 数据看起来很完美
  • 我可以通过 firebug 检查已回答的对象

只有对象(在浏览器中)不会“加载”到商店中。存储数据项保持为零。重新加载后也是如此。我在这里看不到重点。

值得一提的是:第一家商店大约有 50 件商品,而第二家商店有 220 件或更多。我试图为代理设置超时设置。没有帮助。我也试过换店。将存储一设置为网格 2,反之亦然(它由代理中的额外参数设置控制)。只有商品数量较少的商店才能加载良好。

有人知道这个问题吗?这几天我都无法得出结论。

【问题讨论】:

  • 返回的 json 长什么样子,应该是 {"success": true, "issues": [{}, {}, ...] }
  • {total_count: 217 个问题 [对象 { updated_on= "2013/03/12 17:17:55 +0100" , done_ratio= 0 , start_date= "2013/03/12" , mehr.. .},对象{更新时间=“2013/03/13 12:40:38 +0100”,完成比率= 80,开始日期=“2013/03/12”,mehr ...},对象{更新时间=“2013/03 /12 14:39:24 +0100" , done_ratio= 0 , start_date= "2013/03/12" , mehr...}, 97 mehr...] 限制 100 偏移量 0
  • 你还没有配置total和success属性,所以你应该使用默认值。 {“成功”:真,“总数”:217,“问题”:[]}
  • 而你的json数据无效,是你自己生成的,还是使用第三方工具生成的?
  • { total_count: 217, issues:[{},{}, 97 mehr...],limit:100,offset:0} 响应对象中没有“成功”。奇怪的是同一个响应对象被第一个商店消费,没有任何问题。对不起另一个帖子。格式问题:P

标签: rest extjs store extjs4.1


【解决方案1】:

从 Sencha 的文档中查看代理配置。

http://docs.sencha.com/ext-js/4-1/#!/api/Ext.data.reader.Json-cfg-totalProperty

而您的 json 格式不是有效的 json 格式,请在 json 查看器中验证它是否有错误。

编辑:您可以监听数据读取器抛出的异常:http://docs.sencha.com/ext-js/4-1/#!/api/Ext.data.reader.Reader-event-exception

【讨论】:

  • 我在 JSONLint 中检查了交付的 json。它说它是有效的!?一切都应该没问题。它在第一个存储中很好地加载数据。与第二个存储的唯一区别是在请求参数中(顺便说一下,相同的请求 url)设置了一个过滤器来获取特定的对象。我不能同意你的回答。对不起。
  • 设置总属性没有帮助。我对此的理解是,如果服务器提供分页数据,则需要此属性。我的服务器!可以!这样做,但目前还没有。我交付了多达 2000 个未分页的对象。
  • 我将您的答案标记为正确,因为服务器端存在一些错误配置,交付的较大一堆对象包含 1 个不适合模型的对象(必须检查 217 个对象-.- )。这似乎完全破坏了商店。现在,当我解决该问题时,一切都按预期工作。无论如何:奇怪的是,存储没有引发数据无法读取的错误。这可能是对煎茶的要求吗?
  • 您是否在监听 Readers 异常事件,可能它正在引发异常。 docs.sencha.com/ext-js/4-1/#!/api/…
  • 没有。但这是我将来做的标准! :) 我不想再做这样的搜索了……谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-06
  • 2011-12-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多