1

我的 dgrid 有问题...。我有一个 AccordionContainer,在它的每个 ContentPane 中,我放置了一个 dgrid。dgrid 的问题是: 1- 滚动错误:向下滚动时,在特定时刻滚动“跳过”并跳到最后,无法向上滚动并显示第一条记录。(我在 Firebug 中看到错误 TypeError: grid._rows is null 当滚动失败时)。2-尝试更改值:听起来好像没有发出 dgrid-datachange 事件,在编辑值后无法捕获事件。

我认为这些错误与布局中的 dgrid(ContentPane 中的 dgrid,AccordionContainer 中的)有关。我还包括了 DijitRegistry 扩展,但即使有了这个扩展,我也无法摆脱这个错误。我准备了重现错误的小提琴:

https://jsfiddle.net/9ax3q9jw/5/

代码:

var grid = new (declare([OnDemandGrid, DijitRegistry,Selection, Selector, Editor]))({
            collection: tsStore,
            selectionMode: 'none',
            columns:
                [
                    {id: 'timestamp', label:'Timestamp', formatter: function (value,rowIndex) {
                        return value[0];
                    }},
                    {id: 'value', label: 'Value',
                        get: function(value){
                            return value[1];
                        },
                        editor: "dijit/form/TextBox"
                    }
                ],
            showHeader: true
        });
        grid.startup();
        grid.on('dgrid-datachange',function(event){
            alert('Change!');
           console.log('Change: ' + JSON.stringify(event));
        });

        //Add Grid and TextArea to AccordionContainer.
        var cp = new ContentPane({
            title: tsStore.name,
            content: grid
        },"accordionContainer");

任何帮助将不胜感激,谢谢,天使。

4

1 回答 1

4

这个例子有几个问题可能会给你带来问题。

数据

小提琴中使用的商店是使用数组数组创建的,但商店旨在与对象数组一起使用。这是您看到的滚动问题的根源。每个对象中的一个属性应唯一标识该对象(“id”字段)。如果没有条目 ID,网格将无法正确跟踪数据集中的条目。数据数组可以很容易地转换为对象数组,每个条目都有timestampvalue属性,并且存储可以timestamp用作其 ID 属性(它用来唯一标识每条记录的属性)。

var records = [];
var data = _globalData[0].data;
var item;
for (var i = 0; i < data.length; i++) {
    item = data[i];
    records.push({
        timestamp: item[0],
        value: item[1]
    });
}

var tsStore = new declare([Memory, Trackable])({
    data: records,
    idProperty: 'timestamp',
    name: 'Temperature'
});
_t._createTimeSeriesGrids(tsStore);

以这种方式设置存储还可以简化网格列定义。使用字段名称而不是 ID 将允许网格调用formatter具有每个行对象的相应字段值的函数。

columns: [{
    field: 'timestamp',
    label: 'Timestamp',
    formatter: function (value) {
        return value;
    }
}, {
    field: 'value',
    label: 'Value',
    formatter: function (value) {
        return value;
    },
    editor: "dijit/form/TextBox"
}],

正在加载

小提琴使用声明性小部件和 Dojo 的自动解析功能来构建页面。在这种情况下,加载程序回调在执行之前不会等待解析器完成,因此当回调运行时,小部件可能尚未实例化。

有两种方法可以处理这个问题:dojo/ready或显式使用解析器。

parseOnLoad: true,
deps: [
    ...
    dojo/ready,
    dojo/domReady! 
],
callback: function (..., ready) {
    ready(function () {
        var _t = this;
        var _globalData = [];
        ...
    });
}

或者

parseOnLoad: false,
deps: [
    ...
    dojo/parser,
    dojo/domReady! 
],
callback: function (..., parser) {
    parser.parse().then(function () {
        var _t = this;
        var _globalData = [];
        ...
    });
}

布局

将小部件添加到容器时,请使用 Dijit 的方法,例如addChildset('content', ...)。这些通常执行的操作不仅仅是将小部件添加到 DOM,例如启动子小部件。

var cp = new ContentPane({
    title: tsStore.name,
    content: grid
});
registry.byId('accordionContainer').addChild(cp);

代替

var cp = new ContentPane({
    title: tsStore.name,
    content: grid
}, "accordionContainer");

在示例代码中,甚至不需要 ContentPane,因为 dgrid 继承自 DijitRegistry——它可以直接添加为 AccordionContainer 的子项。这也将调用网格的启动方法,因此不需要在代码中显式调用。

registry.byId('accordionContainer').addChild(grid);

最初渲染网格后,通常还需要重新布局网格的容器,以确保其大小合适。

var handle = grid.on('dgrid-refresh-complete', function () {
    registry.byId('accordionContainer').resize();
    // only need to do this the first time
    handle.remove();
});
于 2015-04-14T15:29:04.187 回答