在Meteor 0.8.0(Blaze)中实现可选择的项目列表

Implementing a selectable list of items in Meteor 0.8.0 (Blaze)

本文关键字:可选择 实现 项目 列表 Meteor Blaze      更新时间:2023-09-26

假设我们想要实现一个可选择的项目列表,其中单击列表中的某个内容将通过向其中添加selected类并从列表中的任何其他内容中删除该类来突出显示该项目。Meteor 0.8为我们提供了两种同样可行的方法:

1.反应方式

<template name="dataItem">
    <li class="data-cell {{selected}}">
        {{> dataStuff}}
    </li>
</template>

带有以下代码:

Template.dataItem.events =
  "click .data-cell": (e) ->
    Session.set("selectedTweet", @_id)
Template.dataItem.selected = ->
  if Session.equals("selectedTweet", @_id) then "selected" else ""

在Meteor 0.8之前,此方法很糟糕,因为选择/取消选择会导致整个元素的重新呈现,从而重置其上的任何DOM操作。

优点:

  • Meteor负责所有渲染,没有逻辑错误
  • Blaze只更新DOM中更改的部分,而不重新绘制整个模板

缺点:

  • 如果列表有500个项目长,则每次选择或取消选择某个内容时都会检查500个反应计算

2.纯jQuery方式

<template name="dataItem">
    <li class="data-cell">
        {{> dataStuff}}
    </li>
</template>

代码:

Template.dataItem.events =
  "click .data-cell": (e, t) ->
    $(".data-cell").removeClass("selected")
    t.$(".data-cell").addClass("selected")

在Meteor 0.8之前,这种操作基本上是完全不可能的。

优点:

  • 可能是大型列表中性能效率最高的
  • 无需检查大量的反应性计算

缺点:

  • 在更高级的情况下可能容易出现逻辑错误
  • 感觉我们又回到了jQuery意大利面条的世界

如果你正在实现这样一个列表,你会选择什么?有更好的方法吗?

解决此问题的另一种方法是不存储一个会话变量来说明所选项目,而是将列表中所有项目的选择状态存储在一个单独的Session变量中。类似这样的东西,假设您在allIds:中有一个所有_id的列表

allIds = ...
Template.dataItem.events =
  "click .data-cell": (e) ->
    allIds.forEach((id) -> Session.set("#{id}-selected", ""))
    Session.set("#{@_id}-selected", "selected")
Template.dataItem.selected = ->
  Session.get("#{@_id}-selected")

当然,这假设具有相同值的Session.set不会使反应计算无效;我不确定的事情。如果是这样的话,那么我想人们可以在设置之前检查一下这个值。对这个解决方案不是很满意,但这是解决问题的另一种方法。