Canjs - 何时在迭代列表时使用哪个胡须标记?

sav*_*ger 2 javascript canjs canjs-view

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

我认为这个选择变得有趣的场景是你想要一个默认文本或一个空列表的占位符.

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

这些都不一样.空数组和can.List都将呈现{{#if list}}.

小提琴

{{#each list}}

所以用我们学到的东西#if......

{{#if list.length}}
   <ul>
      {{#each list}}
         <li>...<li>
      {{/each}}
   </ul>
{{else}}
   <i>The list is empty.</i>
{{/if}}
Run Code Online (Sandbox Code Playgroud)

{{#list}}

我认为这是两全其美的.今天我只想到,因为这是一个块助手,所以它支持{{else}}.

{{#list}}
   rendered for each item in list
{{else}}
   rendered once if list is empty
{{/list}}
Run Code Online (Sandbox Code Playgroud)

问题是,这不能产生我们用过的html #each.

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

所以实现似乎取决于标记.很公平.

这就是问题.

据说,#each#list以不同方式更新DOM.来自#each... 的文档

如果键的值是can.List,则在列表更改时更新生成的HTML.当列表中的更改发生时,发生最小量的DOM元素更改.

因此,向列表中添加一个项目,仅渲染该项目,删除项目,仅删除该元素.#list没有记录行为,但我认为它可能会重新渲染整个块.

问题

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

Ale*_*ril 5

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

{{#if list}} 将检查列表的真实价值.这类似于检查任何JS对象的truthy值,并且无论列表内容或长度如何都将为true.

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

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

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

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

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

如果列表中包含内容,则快速记录您的情况......,否则为空列表区域:

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

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

以上应该考虑到这种情况.如果有额外的逻辑,我会考虑编写一个自定义帮助器(取决于逻辑是什么样的).