【问题标题】:Implementing a selectable list of items in Meteor 0.8.0 (Blaze)在 Meteor 0.8.0 (Blaze) 中实现一个可选择的项目列表
【发布时间】:2014-05-31 23:27:10
【问题描述】:

假设我们想要实现一个可选择的项目列表,其中单击列表中的某些内容会突出显示该项目,方法是向其添加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 意大利面条的世界。

如果您要实现这样的列表,您会选择什么?有没有更好的方法?

【问题讨论】:

  • 我不知道您对第一种情况的看法是否正确。来自Deps.dependency 上的文档:'当您调用 Session.equals("weather", "sunny") 时,当前计算依赖于内部依赖关系,如果天气从“下雨天”开始,该依赖关系不会改变”到“多云”。如果您已确认 500 次帮助调用,那么这似乎是意外行为。
  • @user728291 它不会使 499 个其他依赖项无效,但它肯定会检查所有依赖项,这可能比仅通过 500 个 DOM 节点更费力 - 或者是吗?
  • 我认为依赖项是通过检查的值来查找的,比如if ( dependency[ sessionKey ][equalsValue] )。所以你应该得到两个无效的 - 旧的 [key][oldValue] 和 [key][newValue]。
  • 我同意你的观点,这两个无效。尽管如此,仍会检查整个列表。
  • 检查这 499 个依赖项可能非常快。我会建立一些测试,看看你是否能达到一个数字,使一种策略胜过另一种策略。我的猜测是,在您看到两种选择策略之间的任何重大差异之前,渲染整个集合本身会变得很慢。

标签: javascript jquery meteor


【解决方案1】:

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

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 不会使反应式计算无效;我不确定的东西。如果是这种情况,那么我想可以在设置之前检查该值。对这个解决方案不太满意,但这是解决问题的另一种方式。

【讨论】:

  • 所以每次选择某个东西时,你要设置 500 个会话变量的值,并导致 500 个助手重新计算?即使您要使用Session.equals() 来检查匹配,我也看不出这在任何意义上是如何更有效的。此外,它为逻辑错误提供了很多机会——我建议的方法只允许一次选择一个项。
猜你喜欢
  • 2014-05-09
  • 2014-05-12
  • 2022-11-07
  • 2014-12-10
  • 1970-01-01
  • 1970-01-01
  • 2016-06-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多