指点成金-最美分享吧

登录

ContentPane 中的 dgrid - 滚动错误

佚名 举报

技术标签:

【中文标题】ContentPane 中的 dgrid - 滚动错误【英文标题】:dgrid inside ContentPane - Scroll error 【发布时间】:2015-04-14 13:30:30 【问题描述】:

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

我认为这些错误与布局中的 dgrid 相关(dgrid 在 ContentPane 中,在 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");

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

【问题讨论】:

【参考方案1】:

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

数据

小提琴中使用的存储是使用数组数组创建的,但存储旨在与对象数组一起使用。这是您看到的滚动问题的根源。每个对象中的一个属性应唯一标识该对象(“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(););

【讨论】:

嗨,杰森,感谢您的回复。在商店中添加 ID 非常有效。我现在在滚动方面没有问题。但现在更新 dgrid 值的问题仍然存在......我无法“捕捉”dstore/dgrid 上的更新事件......我已经“监听”了 grid.on("dgrid-datachange") 和 tsStore。 on("update") 但似乎编辑器插件没有触发事件....有什么线索吗?提前致谢, grid.on("dgrid-datachange") 应该可以正常工作(原始示例中的侦听器对我来说工作正常)。请注意,它仅在编辑器失去焦点时触发,因此您必须在事件触发之前单击或跳出输入。 要触发商店的更新事件(对于store.on("update", ...)),您需要为编辑器列启用autoSave。网格编辑过程有两个部分——更新网格单元格值,并将这些更改实际保存到网格中。默认情况下,更改值只会更新网格,您必须自己调用grid.save()。在列定义中将 autoSave 设置为 true 将导致网格在值更改时自动将更改保存到存储中。 在小提琴和实际项目中,“dgrid-datachange”对我不起作用。但我找到了解决方案......我必须使用编辑器在列的定义中添加“字段”属性,现在它可以工作了。我必须查看 Editor.js 代码,它需要一个 column.field 属性。 关于商店更新...是的,我尝试过使用 autoSave 属性。我试过用 autoSave 和没有它和 grid.save()

以上是关于ContentPane 中的 dgrid - 滚动错误的主要内容,如果未能解决你的问题,请参考以下文章