2

在 Can.js 中似乎有几种不同的方法可以做同样的事情,这很棒!但有些方法的工作方式与其他方法略有不同,并且会影响 DOM 的呈现和更新方式。如果有人能澄清细微差别,我将不胜感激。

我认为这种选择变得有趣的场景是当您想要一些默认文本或空列表的占位符时。

{{#if list}} 和 {{#if list.length}}

这些不一样。一个空数组和一个 can.List 都会为{{#if list}}.

小提琴

{{#每个列表}}

因此,使用我们学到的#if...

{{#if list.length}}
   <ul>
      {{#each list}}
         <li>...<li>
      {{/each}}
   </ul>
{{else}}
   <i>The list is empty.</i>
{{/if}}

{{#列表}}

我认为这是为了两全其美。我今天才想到,由于这是一个块助手,它支持{{else}}.

{{#list}}
   rendered for each item in list
{{else}}
   rendered once if list is empty
{{/list}}

问题是,这不能生成我们用#each.

  • 将整个内容包装在一个<ul>标签中,无论列表是否为空,它都会被渲染
  • 将标签粘贴<ul>在第一个块(正块?肯定?)并且每次都呈现

所以实现似乎依赖于标记。很公平。

这就是问题所在。

据说,#each#list以不同的方式更新 DOM。从文档中#each...

如果键的值是 can.List,则生成的 HTML 会在列表更改时更新。当列表发生变化时,只发生最少量的 DOM 元素变化

因此,将一项添加到列表中,仅呈现该项,删除一项,仅删除该元素。的行为#list没有记录,但我的印象是它可能会重新渲染整个块。

问题

哪个最好?除了更简洁之外,我不确定#list它有什么优势,那么为什么作者建议它是首选呢?

4

1 回答 1

5

假设 list 是一个 can.List 实例:

{{#if list}} 将检查列表的真实值。这类似于检查任何 JS 对象的真实值,无论列表内容或长度如何,结果都会为 true。

{{#if list.length}}将检查长度属性的真实值。如果您有一个空列表,则长度将为 0,因此 #if 将导致 false 并且不会呈现任何内容。如果长度 >= 1,这将导致 true 并且将呈现 #if 的内容。

#each并且#list都遍历 can.List 的实例,但是我们以不同的方式设置绑定。

#each将在每个被迭代的项目上设置绑定,而#list不会。这在两种情况下有所不同:

1)你有一个很大的列表,在初始渲染后计划进行最少的更新。在这种情况下,#list可能会更有利,因为会有更快的初始渲染。#list但是,如果列表的任何部分发生更改,则将重新处理整个区域。

2)你有一个很大的列表,在初始渲染后计划了许多更新。例如,具有许多可编辑字段列的网格。在这种情况下,您很多人都想使用#each,即使它在初始渲染时会更慢(我们正在设置更多绑定),但您将获得更快的更新,因为现在有很多部分。

快速说明您的 if list has contents ...,否则为空列表区域:

{{#each items}} 循环遍历列表项!{{/每个}}

{{^if items.length}} 显示是否没有项目!{{/如果}}

以上应该说明这种情况。如果有额外的逻辑,我会考虑编写一个自定义助手(取决于逻辑的样子)。

于 2014-10-03T16:09:18.427 回答