Ember.js 集合迭代中的位置索引

Posted

技术标签:

【中文标题】Ember.js 集合迭代中的位置索引【英文标题】:Positional index in Ember.js collections iteration 【发布时间】:2012-02-10 20:23:31 【问题描述】:

有没有办法在 ember.js 的迭代过程中获取位置索引?

#each itemsArray
     name
/each

我正在寻找一种方法来获得类似的东西:

#each itemsArray
    name - indexth place.
/each

更新:

根据@ebryn 的评论,以下代码可以在不使用每个项目的嵌套视图的情况下工作:

<script type="text/x-handlebars">    
    #collection contentBinding="App.peopleController"
        Index contentIndex: content.name <br />
    /collection
</script>​

http://jsfiddle.net/WSwna/14/

虽然有类似adjustedIndex的东西,但还是需要嵌套视图。

【问题讨论】:

Accessing Index in #each in emberjs的可能重复 Ember 1.11 使这变得微不足道。如果您使用的是 Ember 1.11+,请参阅下面的答案。 【参考方案1】:

目前这不是 Handlebars 或 Ember.Handlebars 的功能。我们在#collection/Ember.CollectionView 中有contentIndex。我认为支持#each 也很有用。请在 GitHub 存储库中提交问题:https://github.com/emberjs/ember.js/issues

【讨论】:

更新至此:Handelbars 获得了support for @index。它还不能在 Ember.Handlebars 中使用,但我想它迟早会出现。【参考方案2】:

我想你也可以这样做

//add index property to all each queries
Handlebars.registerHelper('each', function(context, block) 
    var ret = "";
    for(var i=0, j=context.length; i<j; i++) 
        context[i].index = i;
        ret = ret + block(context[i]);
    
    return ret;
);

【讨论】:

我已经这样做了,但我觉得重写内置迭代器的行为是不对的。【参考方案3】:

实际上是的,您可以使用 each 帮助器获取当前索引的位置。您必须为列表中的每个项目创建一个视图,然后使用_parentView.contentIndex

<script type="text/x-handlebars">
#each App.peopleController
  #view App.PersonView contentBinding="this"
    Index _parentView.contentIndex: content.name adjustedIndex <br />
  /view
/each
</script>

App = Ember.Application.create();

App.peopleController = Ember.ArrayController.create(
  content: [  name: 'Roy' ,  name: 'Mike' ,  name: 'Lucy'  ]
);

App.PersonView = Ember.View.extend(Ember.Metamorph, 
  content: null,
  // Just to show you can get the current index here too...
  adjustedIndex: function() 
    return this.getPath('_parentView.contentIndex') + 1;
  .property()
);

有关工作示例,请参阅 this jsFiddle。

【讨论】:

能否请您告诉我为什么在扩展视图时需要传入 Ember.Metamorph 行为? 你“不需要”,但是添加 Ember.Metamorph mixin 使整个设置比臃肿的 @987654327 更像一个普通的 each 助手(这里谈论速度和内存资源) @帮手。如果您查看两者的来源并进行比较,您就会明白我的意思。对于大量数据,它会产生影响。 您的代码似乎不适用于 VIEW_PRESERVES_CONTEXT 设置为 true 的 0.9.8.1 我得到:预期的哈希或 Mixin 实例,得到 [object Undefined] 如果人们偶然发现它试图找到一个有效的答案,你可以更新这个答案会非常好/真的很有帮助! :)【参考方案4】:

我已经使用集合修改了一点 ud3323 解决方案。 在这里查看:http://jsfiddle.net/johngouf/WSwna/13/

<script type="text/x-handlebars">    
#collection contentBinding="App.peopleController"
  #view App.PersonView contentBinding="this"
    Index _parentView.contentIndex: content.name adjustedIndex <br />
  /view
/collection
</script>

App = Ember.Application.create();
App.peopleController = Ember.ArrayController.create(
 content: [  name: 'Roy' ,  name: 'Mike' ,  name: 'Lucy'  ]
);

App.PersonView = Ember.View.extend(
 content: null,
 // Just to show you can get the current index here too...
 adjustedIndex: function() 
    return this.getPath('_parentView.contentIndex') + 1;
 .property()
);

​​​

【讨论】:

【参考方案5】:

从 Ember 9.8 和 pre-1.0 开始,您可以使用视图包装“contentIndex”,以便获取虚拟父级(#each)。如果您不添加视图,您的上下文最终会成为主模板、列表中的项目或您使用#with 手动设置的任何内容。从 JS 方面获取 #each 并非不可能,但翻阅这些子视图会更加痛苦。

#each App.peopleController
    #view
        Index view._parentView.contentIndex: name <br />
    /view
/each

...OR...

#each people in App.peopleController
    #view
        Index view._parentView.contentIndex: people.name <br />
    /view
/each

以防万一你想要一个小提琴手。

DEMO

注意:如果您想修改数字,您可以创建一个视图并执行this.get("_parentView.contentIndex") 以获取索引。

【讨论】:

【参考方案6】:

在 RC6 中,CollectionView 为每个呈现的集合视图提供 contentIndex 属性。 Each helper 在其实现中使用CollectionView,所以你可以通过这种方式访问​​索引:

#each itemsArray
    _view.contentIndex
/each

【讨论】:

当我在每个控制器中使用它时,我会得到奇怪的数字 这对我有用 - 我的控制器中有一个数组,我只是做这样的事情:#each前景索引_view.contentIndex:name /每个 不指定itemViewClass,我们可以使用_view.contentIndex。但这在#each 中的#if 助手中不起作用。为此,我们需要使用: #each model itemViewClass="Ember.View" #if someCondition view.contentIndex /if /each "指定一个 itemViewClass"【参考方案7】:

这是一个老问题,但仍然得到很多点击。在当前版本的 Ember.JS 中,可以使用 _view.contentIndex 在循环内显示当前索引。

#each
    Index: _view.contentIndex
/each

如果您需要调整索引(例如从 1 开始),则可以创建可重用的帮助器 increment

Ember.Handlebars.registerBoundHelper('increment', function(integer) 
    return integer + 1;
);

那么你会按照以下方式使用它

#each
    Index: increment _view.contentIndex
/each

更新

从 ember 1.11 开始,您也可以这样做

#each people as |person index|
   Index: increment index
/each

【讨论】:

【参考方案8】:

从 Ember 1.11.0 开始,indexeach 块中的可选参数:

#each items as |item index|
  item.name is at index index
/each

【讨论】:

这正是我要找的,谢谢史蒂夫的帮助!

以上是关于Ember.js 集合迭代中的位置索引的主要内容,如果未能解决你的问题,请参考以下文章

Ember.js - ArrayController 和 CollectionView 之间的区别

Ember.js - 前端框架(原创翻译)

toastr 和 ember.js

Ember.js 中的视图与组件

ember.js 控制器中的排序模型

Ember.js 路由器和 initialState 中的嵌套路由