我们在 2 月份 宣布了网格项目。从那时起,我们完成了前三个阶段,现在正在开始第四个阶段。在这篇文章中,我们将看看到目前为止我们构建了什么。
这是我们设计为“零功能网格”的东西。它所做的只是增强 HTML 表格,但它在做得很好同时提供了各种其他功能的正确钩子,这些功能可以添加到它之上。事实证明这非常有用,因为有很多事情是普通 HTML 表格做不到的。使用网格,您将获得
- 使用 CSS 框架进行样式设置,使其成为 ThemeRoller 就绪的
- 一个基于表格标题的适当标题栏
- 表格主体滚动所需的标记和样式,同时保持标题固定
网格的 API 控制渲染什么内容以及如何呈现
- columns 选项指定要渲染的列。如果未指定,它将选取现有的表格标题元素。
- rowTemplate 选项允许网格从自定义模板渲染每一行。如果未提供此选项,则每行将根据 columns 选项生成。
- source 选项指定要渲染的内容,以对象数组的形式。如果未指定,则使用现有的表格行。
- 默认情况下,网格的主体随着行数的增加而增长。使用 heightStyle: 'fill',它会保持固定高度,如果存在更多行,则主体将开始滚动。
- 从现有的表格标题中获取列信息时,将读取某些 data-attributes。网格本身只使用 data-property 属性(以及每个标题单元格的实际文本),但 dataFields 选项指定其他组件可以使用的一些其他属性,例如“type”、“culture”和“format”来配置本地排序和过滤。如果网格插件处理其他 data attributes,将这些属性添加到 dataFields 选项中会使它们作为 columns 选项的一部分自动可用。
到目前为止,我们只有 一个增强的表格,但很多时候,网格需要从某个远程资源获取数据。这就是 Dataview 的用武之地。
Dataview 是一个用于检索内容的底层抽象。它有一个用于指定要检索的内容的 API,以及一个 SPI(服务提供者接口),由提供该内容的组件实现。它内置了用于过滤、排序和分页的选项,并且设计使添加更多选项变得容易,例如分组。API 默认情况下是异步的,即使对于本地数据也是如此,这样所有依赖 Dataview 的组件都可以同时使用本地数据和远程数据。
Dataview 只依赖于 Widget 和 Observable(我们将在下面介绍),但不依赖于 Grid。这使得 Dataview 可以用于各种环境。例如,它可以为产品列表提供支持,例如 eBay 或亚马逊上的产品列表,表格呈现形式并不适合。
Dataview SPI 使得从头编写实现以及创建可重用的扩展变得容易。
例如,我们可以使用 自定义 dataview 作为自动完成小部件的输入。相同的数据也显示在输入字段下方的网格中。这演示了 Dataview 如何用于多个表示,其中每个表示都自行决定要显示哪些数据。
至于可重用的扩展,我们目前已经实现了三个
- localDataview 获取一个输入数组,并对该数组进行排序、分页和过滤。它使用 Globalize(见下文)来实现本地化数字和日期的过滤和排序。当与表格上的网格结合使用现有内容(不指定 source 选项)时,您将获得 一个完整的 tablesorter。
- odataDataview 获取一个资源 URL,该 URL 指向一个理解 OData,开放数据协议 的 Web 服务。虽然我们的实现还没有涵盖所有 OData 选项,但您可以使用它来排序、过滤和分页,而无需实现任何自定义请求/响应映射。我们有一个使用基于 OData 的 Netflix API 的 网格示例。
- preloaderDataview 包装一个 Dataview 并调整分页行为以加载比渲染的更多数据,在预加载另一批数据之前进行本地分页。在这个 Flickr API 幻灯片示例 中,我们预加载了 API 响应和实际图像。这将所有加载推送到后台,允许用户在没有中断的情况下翻页浏览图像。
所有这三个都需要在实际项目中进行测试,然后我们才能认为它们是稳定的。我们也在寻找可能错过的其他 dataview 用例。
数据绑定目前是较新的 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。下一步是为数组绑定找到一个抽象,这将消除网格以及 todo-app 演示 的一些开销。
将 Observable 与网格结合使用时,我们可以轻松地添加编辑功能。在我们的 网格编辑演示 中,您可以向表格中添加、编辑和删除开发人员。结果通过 localStorage 持久化。
与其添加带有“编辑”和“删除”按钮的自定义列,我们可以使用可选择交互来选择一行或多行,然后与所选内容进行交互。在该演示中,selected
数组也是一个可观察数组,第二个网格显示了它。请注意,您可以在一页上选择行,然后转到下一页(您可能需要添加几个开发人员才能显示第二页),使用命令/ctrl-单击(以扩展选择范围)选择更多行,它将在第二个网格中显示所有这些行。选择状态与视觉表示分离,使得跨多个页面进行选择变得非常容易。
Globalize 最初是作为 jquery-global 插件开始的。我们将其作为网格项目的一部分重新编写,使其独立于 jQuery,允许在客户端和服务器上使用。我们的 localDataview 实现(如上所述)使用它,它也位于自定义输入之后,例如Spinner 和Timepicker。
这三个自定义输入正在作为网格项目的一部分开发。它们旨在用于网格中的内联编辑,以及在常规表单或网站中独立使用。我们即将在 master 中发布所有这三个,以便将它们作为 1.9 的一部分发布。
还有更多…
我们仍在继续进行Template、Datepicker 和其他Custom Inputs 的工作。一旦我们拥有更稳定的解决方案,我们将对这些解决方案进行汇报。
接下来
我们正在完成现有的组件,并开始 Stage 4。有关详细信息,请查看主要的网格 wiki 页面。
那么,什么时候完成呢?
我们的Roadmap 将网格放在 2.1 版本中,而 jQuery UI 的主要重点是 1.9。换句话说,在我们能够将网格放入稳定版本并与所有其他组件一起支持它之前,还有很多事情要做。同时,我们鼓励您现在就开始测试上面列出的功能。网格、Observable 和 Dataview 非常稳定并且运行良好。Globalize 是一个单独的项目,如果您想在客户端支持本地化数字和日期处理,现在应该开始使用它。
我们重视您的意见和帮助。请使用Developing jQuery UI 论坛,评论单个 wiki 页面或访问我们的 IRC(#jqueryui-dev 在 Freenode 上)。如果您找到了某个问题的解决方案,请发送一个 pull 请求。