65.9K
CodeProject 正在变化。 阅读更多。
Home

TableGrid

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.80/5 (2投票s)

2015年10月23日

CPOL

7分钟阅读

viewsIcon

11139

downloadIcon

117

Google+ 帖子标题和标签列表。

引言

在 Google+ 上发帖后,我发现没有简单的方法来搜索包含特定标签的帖子。我的想法是列出 Google+ 帖子的标题和标签。

图 1a:我的 Google+ 帖子标题和标签列表的设计

通过此界面,用户可以看到我所有帖子的标题以及标签,因此可以相对容易地通过列表关注某个主题。

该项目包含一个简单的 HTML UI,使用 JavaScript 构建和填充;JSON 数据用于保存标题和标签;将来可以开发它以使用 Google+ API 动态获取一些数据。[但对 Google+ API 的快速查看让我相信无法以简单的格式生成我所需的数据。因此,对于这个项目,我计划首先手动输入数据,但其格式可以通过自动化从合适的来源复制,因此使用了 JSON。]

核心任务是创建一个可以为表格或网格生成 HTML 的行构建器。因此,主类名为 TableGrid。但是,其中包含了一些辅助函数。

当前项目使用此类别构建 UI,并使用 CCS 样式。

git 仓库在 GitHub 上,以下标签对应于本文

背景

[如果您只对代码感兴趣,可以跳过此部分。]

CodeProject 有很多很棒的文章,参与其中似乎是巩固知识的好方法。但是,在撰写自己的文章时,似乎很难直接将其发展到符合 Codeproject 要求。我需要一个循序渐进的过程。

偶尔,我可能会找到一个关于我收集了一些信息的 Stackoverflow 问题,然后我可以将我的笔记作为答案发布。[尽管问答流通常就像走进风洞。]

然后我开始在 Google+ g+ 上发帖,在那里你可以随意发布琐碎或复杂的帖子,并根据需要多次重新编辑。因此,这些想法并没有因为不适合写文章而被放弃,而是开始填满 g+。

我现在已经绕了一圈,因为我将描述一个从小项目,这个项目源于我试图控制我的 g+ 帖子。

文章内容

该项目包含以下文件

  • HtmlTools.js - 包含一个用于构建表格和网格并从数据填充它们的类 TableGrid
  • googlePostsList.html - 这是一个简单的网页,用于演示此项目中的 UI
  • googlePostsList.css - 附带的 CSS
  • codeBehind.js - 在此演示中使用 TableGrid
  • Data.js - 包含此示例的 JSON 数据

尽管这不是一个困难的项目,但它涉及多个主题。为了在这篇文章中单独考虑这些主题,将首先描述前端 UI 和样式。然后讨论数据需求,接着是 TableGrid 类及其开发。

用户界面和样式

图 1a 展示了 HTMLCSS 的最终渲染。HTML 结构是交替的 div,因此它们可以形成两列或一堆交替的标签和标题。

图 2a:替代布局,帖子标题和标签堆叠,与图 1a 比较

清单 1a:单个帖子的 html

<div class="list_container">
    <div class="post_tags">
         <span class="hashtag_button">hashtag1</span>
         <span class="hashtag_button">hashtag2</span>
    </div>
    <div class="post_title">
        <a href="https://...">
        Title</a>
    </div>
</div>

CSS 中,为了获得 div 所需的布局行为,它们的 display 属性设置为 inline-block,并且通过增加第二个 div 中的 line-height 来实现在两种排列中每个帖子下方的空白区域的位置。

.post_tags {
  display: inline-block;
  vertical-align: top;
}

.post_title {
  display: inline-block;
  line-height: 22px;
  ...
}

标签和标题的外观(在 CSShashtag_buttonpost_title>a 中设置)被设置为使列表项看起来与 Google+ 相似。

.hashtag_button {
  background-color: #EEE;
  border-color: #DDD;
  ...
}

.post_title>a {
  color: #404040;
  font-style: italic;
  ...
}

请注意,hashtag_button 完全专注于这种外观,因此与容器类 post_tags 分离。

hashtagsdivpost_tags 内部形成一个水平堆栈,text-align 的值控制堆栈方向。然后在响应式布局更改部分——其中也定义了各种 width 设置——text-align 的行为针对每种布局设置不同。

对于像图 1a 这样的全尺寸,这是默认值。

  .post_tags {
    text-align: right;
    width: 30%
  }

对于像图 2a 这样的小尺寸,由媒体规则控制。

@media screen and (min-width:0em) and (max-width:40em){
...
  .post_tags {
    text-align: left;
    width: 100%;
  }
...
}

Data

图 1a 中的 UI 示例显示了每个帖子所需的一些数据

  • 标签
  • title

此外,UI 使用帖子标题作为超链接,帖子的 URL 作为链接。

  • Google 帖子网址

在 Google+ 上关注一个标签,它会被添加到基本 URL 中

  • plus.google.com/explore/

例如:plus.google.com/explore/hashtag [注意:此链接在当前示例中未实现。] 这不需要为每个帖子提供额外的数据,因此单个帖子的 JSON 数据格式如下。

清单 2a:单个的 JSON 数据

{   tagList: ["tag1", "tag2"], 
    title: "Title of post",
    link:"https:\\ ... "
}

因此,每个帖子的数据都作为数组中的一个元素存储。

TableGrid

正如引言中所述,后台代码的要求是从数据行构建 HTML 列表。这是一项常见的任务,有许多解决方案,本解决方案在浏览器中使用 JavaScript,利用专门用于此任务的 TableGrid 类来完成此操作。

我已经展示了我想要在这里使用的特定数据,但我真的想最大限度地提高我正在开发的代码的可重用性,以及我可以处理的数据。为了确定最佳架构,我们将比较层次结构和简单的二维表。

从最简单的开始,例如动物列表,可以将其渲染为 HTML 表格中的列表,每行都会生成一个如下所示的项

<tr> <td> dog </td> </tr>

此示例中的某些功能可以在一般情况下重复使用。

  • 遍历数据行

此外,表格行总是以相同的序列 <tr> ... </tr> 开始和结束。这种行的包装也可以在更复杂的结构中分离。

  • 将行的包装与数据格式化分开。

然而,在这种情况下数据的处理是微不足道的,仅仅用 <td>数据</td> 包装数据,但这通常是不够的。我们还希望能够处理各种类型的数据,从单个字符串和数组到更复杂的层次结构,并将它们添加到表格或其他结构中。

接下来考虑一个更复杂的例子。例如前面建议的使用 JSON 数据,它允许分层数据集。那么问题就是找到一个既能满足简单例子又能满足复杂例子的模式。此外,我们需要能够构建比简单表格更复杂的结构。我选择让开发人员定义一个函数,该函数将数据行作为变量接收,然后可以构建任何结构。

  • 可自定义函数,将数据行转换为格式化输出。

从上述要求推导出的模式如图 3a 所示。

图 3a:TableGrid 类和使用模式

为了演示这一点,我们将继续这个例子。从清单 1a 中我们可以看到,每一行都以 <div class="list_container"> 作为前缀,以 </div> 作为后缀。然后,内部包含数据的元素可以从清单 2a 中的 JSON 数据在自定义行构建器函数中构建,该函数在遍历行时被调用。

function myLineBuilder(data){
    s = '\n\t<div class="post_tags">\n\t\t'
    s += HtmlBuilder_wrapArray(data.tagList, 
    ' <span class="hashtag_button">', '</span>')
    s += '\n\t</div>'
    s += '\n\t<div class="post_title">'
    s += '\n\t\t<a href="'+data.link+'/">'
    s += '\n\t\t'+data.title+'</a>'
    s += '\n\t</div>'
    return s
}

请注意,HtmlBuilder_wrapArray 函数是 HtmlTools.js 中包含的一个辅助函数,此处用于为 hashtags 数组 data.tagList 生成 span 标签。

现在我们可以将这些插入到 TableGrid

tg = new TableGrid()
tg.setLineBuilder( myLineBuilder, 
'\n<div class="list_container">', '\n</div>')

然后进行构建并请求结果

tg.buildRows(myPostList)
htmlString = tg.getBlock()

其中 myPostList 是每个帖子的数据行数组。

实现 TableGrid 的代码是

function TableGrid(){
    this.linebuilder
    this.linePrefix
    this.lineSuffix
    this.block=""
    
    this.setLineBuilder=function(lb,pre,suf){
      this.linebuilder=lb
      this.linePrefix=pre
      this.lineSuffix=suf
      this.block = ""
     }
     
     this.buildRows=function(table){
        //will loop over the top layer and pass each item to line builder
        for(var i=0; i<table.length; i++){
            tg.buildLine(table[i])
        }
    }
    
    this.buildLine=function(data){
        //prefix line
        s = this.linePrefix

        //run the line builder callback
        s += this.linebuilder(data)
        
        //suffix line
        s += this.lineSuffix
        
        this.block += s
    }
    
    this.getBlock=function(){ return this.block; }
}

用法回顾

  • 构建数据结构
  • 设计数据的 HTML 视图
  • 将 HTML 结构分解为行包装器、行内容和表格包装器
  • 编写行构建器
  • 初始化 TableGrid
  • 完成此操作后,数据即可发送到 TableGrid.buildRows

TableGrid 的实例本身可以通过发送新的数据集来重复使用。

显然,对于构建简单的表格,这导致了一个相对复杂的方法。为了保持简单性,为简单表格提供了创建函数。这还有一个额外的好处,即这些预定义的类实例也可以用于测试。本文不再赘述,但已在上传的项目中。

摘要

此项目涉及少量 HTMLJavaScriptJSONCCS

感谢阅读,请留下评论。

历史

  • 版本 1
© . All rights reserved.