jQuery UI 网格现状

发布于 作者

我们在 2 月份宣布了网格项目。从那时起,我们完成了前三个阶段,现在正在开始第四个阶段。在这篇文章中,我们将看看我们到目前为止所构建的内容。

网格

这就是我们设计为“零功能网格”的东西。它所做的只是增强 HTML 表格,但它做得很好,同时也为我们可以添加到其中的各种其他功能提供了合适的挂钩。事实证明这非常有用,因为有很多事情是普通的 HTML 表格做不到的。使用网格,您将获得

  • 使用 CSS 框架进行样式设置,使其支持 ThemeRoller
  • 基于表格标题的适当标题栏
  • 表格主体滚动所需的标记和样式,同时保持标题固定

网格的 API 控制要渲染什么内容以及如何呈现它

  • columns 选项指定要渲染的列。如果没有指定,它将选择现有的表格标题元素。
  • rowTemplate 选项允许网格从自定义模板渲染每一行。如果没有提供此选项,则将根据 columns 选项生成每一行。
  • source 选项指定要渲染的内容,形式为纯对象数组。如果未指定,则使用现有的表格行。
  • 默认情况下,网格的主体随着行数的增加而增长。使用 heightStyle: ‘fill’,它保持固定高度,如果存在更多行,则主体将开始滚动。
  • 从现有的表格标题中获取列信息时,会读取某些数据属性。网格本身仅使用 data-property 属性(以及每个标题单元格的实际文本),但 dataFields 选项指定其他组件可以使用的一些其他属性,例如“type”、“culture”和“format”来配置本地排序和过滤。如果网格附加组件处理其他数据属性,将这些属性添加到 dataFields 选项中将使其自动作为 columns 选项的一部分提供。

到目前为止,我们只有一个增强的表格,但很多时候,网格需要从某个远程资源获取数据。这就是 Dataview 派上用场的地方。

Dataview

Dataview 是用于检索内容的低级抽象。它有一个 API 用于指定要检索的内容,以及一个 SPI(服务提供者接口),由提供该内容的组件实现。它有用于过滤、排序和分页的内置选项,并且设计使其易于添加更多选项,如分组。API 默认情况下是异步的,即使对于本地数据也是如此,因此所有依赖 Dataview 的组件都可以使用本地数据和远程数据。

Dataview 仅依赖 Widget 和 Observable(我们将在下面介绍),而不依赖 Grid。这允许 Dataview 用于各种环境。例如,它可以为产品列表提供动力,例如 eBay 或 Amazon 上的产品列表,其中表格展示不是正确的格式。

Dataview SPI 使得从头编写实现以及创建可重用扩展变得容易。

例如,我们可以使用自定义 dataview 作为 Autocomplete 小部件的输入。相同的数据也会显示在输入字段下方的网格中。这演示了如何在一个 dataview 中使用多种表示形式,其中每个表示形式都自行决定要显示哪些数据。

至于可重用扩展,我们目前已经实现了三个

  1. localDataview 获取一个输入数组,并在该数组上执行排序、分页和过滤。它使用 Globalize(见下文)来实现本地化数字和日期的过滤和排序。当与带有现有内容的表格上的网格结合使用时(不指定 source 选项),您将获得一个完整的 tablesorter
  2. odataDataview 获取一个资源 URL,指向理解OData(开放数据协议) 的 Web 服务。虽然我们的实现尚未涵盖所有 OData 选项,但您可以使用它进行排序、过滤和分页,而无需实现任何自定义请求/响应映射。我们有一个使用基于 OData 的 Netflix API 的网格示例
  3. preloaderDataview 包裹一个 Dataview,并调整分页行为以加载比渲染的更多数据,在预加载另一个批次之前本地分页。在这个Flickr API 幻灯片示例 中,我们预加载了 API 响应和实际图像。这将所有加载推送到后台,允许用户在没有中断的情况下浏览图像。

所有三个都需要在实际项目中进行测试,然后我们才能认为它们是稳定的。我们还在寻找可能遗漏的 dataview 的其他用例。

Observable

数据绑定目前是较新的 JavaScript 框架中的一个常见主题,有各种相互竞争的解决方案可用。我们还没有完整的替代方案,但我们已经开发了一个低级抽象,它可能在将来为数据绑定组件提供动力。我们称这个抽象为 Observable。它提供了一个 API,用于对纯 JavaScript 对象和数组进行更改,这些更改可以通过监听每个更改触发的事件来观察。我们设计 Observable 使其方法和事件数量很少,目的是使其易于在其他环境中实现相同的 API。这些事件是

  • change: 在一个或多个属性更改后,在对象上触发。
  • insert: 在数组中插入一个或多个新项目后,触发。
  • remove: 在从数组中删除一个或多个项目后,触发。
  • replaceAll: 在替换数组中的所有项目后,触发。

最后一个事件乍一看可能很奇怪,但这使得创建 dataview、将其传递给网格、让网格订阅该 dataview 输出数组上的事件,然后在 dataview 更新时自我更新成为可能。

对于所有四个事件,Observable 都提供方法对应项

  • property: 用于处理对象
  • insert、remove 和 replaceAll: 用于处理数组。

两种情况下的用法都一致

  • $.observable( object ).property( “name”, “Fred” );
  • $.observable( array ).insert({ name: “Peter” });

我们仍在开发 Observable。下一步是为数组绑定找到一个抽象,这将消除来自网格以及来自待办事项应用程序演示 的一些开销。

将 Observable 与 Grid 结合使用时,我们可以轻松地添加编辑功能。在我们的网格编辑演示 中,您可以从表格中添加、编辑和删除开发人员。结果通过 localStorage 持久化。

我们可以使用可选择交互来选择一行或多行,然后与选择进行交互,而不是添加具有“编辑”和“删除”按钮的自定义列。在该演示中,selected 数组也是一个 observable 数组,第二个网格显示该数组。请注意,您可以选择一个页面上的行,然后转到下一页(您可能需要添加一些开发人员才能显示第二页),使用 command/ctrl-click 选择更多行(以扩展选择),它将在第二个网格中显示所有这些行。选择状态与视觉表示形式分离,使跨多个页面的选择变得非常容易。

Globalize

Globalize 最初是作为 jquery-global 插件开始的。我们将其作为网格项目的一部分重写,使其独立于 jQuery,允许在客户端和服务器 上使用。我们的 localDataview 实现(上面提到)使用它,它还在自定义输入(如SpinnerTimepicker)的背后。

MaskTimepickerSelectmenu

这三个自定义输入正在作为网格项目的一部分开发。它们旨在用在网格中用于内联编辑,以及独立于普通表单或网站中使用。我们很快就会将这三个都放到 master 中,以便将它们作为 1.9 的一部分发布。

还有更多…

我们仍在开发TemplateDatepicker 和其他自定义输入。一旦我们有了更稳定的解决方案,我们将汇报这些信息。

接下来

我们正在完成现有的组件,并开始第 4 阶段。有关详细信息,请查看主要的网格维基页面

那么,什么时候完成呢?

我们的路线图 将网格列在 2.1 版本中,而 jQuery UI 的主要重点是 1.9。换句话说,在我们能够将网格纳入稳定版本并与所有其他组件一起支持它之前,还有很多事情要做。与此同时,我们鼓励您现在就开始测试上面概述的功能。网格、Observable 和 Dataview 都非常稳定,运行良好。Globalize 是一个单独的项目,如果您想在客户端支持本地化数字和日期处理,您应该立即开始使用它。

我们重视您的意见和帮助。请使用开发 jQuery UI 论坛,在各个维基页面上发表评论,或在 IRC 上与我们联系(Freenode 上的 #jqueryui-dev)。如果您找到了某个问题的解决方案,请发送拉取请求

关于“jQuery UI 网格现状”的 22 个想法

  1. @ivan: 与 Backbone 的 Model 和 Collection 对象有一些重叠,但仅此而已。考虑到 Backbone 的整体范围有限,您应该可以使用 Observable 和 Dataview 实现非常类似的应用程序。如果您需要路由器,请使用 history.js。

  2. 为什么在有 datatables 的情况下还要开发网格功能呢?
    它不仅是我见过的最好的插件,而且还拥有我所能想到的表格的所有功能,为什么要做两遍工作呢?oO

  3. 顺便说一下,它甚至有 jQuery UI 兼容性、主题等等!
    我不明白为什么有必要…

  4. mattreyuk 说:

    我有点同意 @Conic 的观点——我不确定它做了 Datatables 没有做的事情。

  5. @Conic 和 mattreyuk——它将与其他 API 一起进行测试,以便在未来的版本中发布,并反映 jQuery UI 其余部分的内部一致性。我已经计划将我所有旧的第三方插件驱动的垃圾转换成这个,因为我知道错误会在合理的范围内消失,而且集成将大大降低我的代码维护开销。您是否曾经因为需要第三方插件而不得不进行重大重构?这可能不适合所有人,但对我来说确实很好。

  6. 不错的工作,但为什么您要开发这样一个复杂的组件,而像工具提示这样的更简单、更常用功能却已经等了一年多?

  7. John Reilly 说:

    1.9 的发布日期是哪天?我真的很期待使用菜单、菜单栏和工具提示。

    我很高兴网格和树组件正在开发中,但说实话,现在 jqgrid 和 jstree 已经满足我的需求。

  8. @ninsky——我们特别注意确保网格的开发工作与 1.9、菜单、工具提示、微调器等其他新部件的开发同步进行(并且不会减缓进度)。因此,工具提示将在最终的稳定版本中发布,就像它原本会发布一样,甚至可能更早。菜单、微调器、遮罩、时间选择器等等也是如此。如果有什么区别的话,这些(以及其他)都得到了更多关注和重点,而不是更少,这得益于 jQuery UI 网格项目和一些使其成为可能的专用资源。

    @John Reilly——我们不设置发布日期,我们一直开发到完成,完成之后就发布。您可以查看路线图来了解 1.9 最终版本的剩余工作:http://wiki.jqueryui.com/Roadmap。这个时间将以月为单位,而不是以周或年为单位。

  9. 不错的工作……如果它已经准备好了,我会在我的个人项目中使用它。如果能证明有用,我当然乐意测试预发布版本……

  10. shawn 说:

    使用 Observable,为什么不使用 prop() 而不是 property() 来简化和与 jQuery 核心保持一致?

  11. @Josh:我们的 view.jqueryui.com 服务器进行了一项更改,将所有分支移动到 /branches。我已经更新了演示链接,它们现在应该都可以正常工作了。

  12. Hermes 说:

    我一直非常努力地使用 jqGrid,它是一个使用 jQuery UI 的非常强大的网格实现,在许多方面类似于 Datatables。这项之前的工作如何融入其中?如果它确实要融入的话……从表面上看,这个网格非常宽泛,而 jqGrid 和 Datatables 则拥有非常密集和重要的功能集,涵盖更小的使用范围。当然,这仅仅是一个开始。我发现面向 OData 的方法非常有趣,以及数据访问的便捷性如何能够互连资源。这是新语义网络中美丽而可怕的事情之一!

  13. @Chris:在网格编辑演示中,您可以看到单元格选择的操作。它目前还处于实验阶段。

    @Hermes: 构建小型简洁的组件是本项目的主要目标。这比直接构建一个功能齐全的网格需要更多时间,但从长远来看,它提供了更大的价值。