简体   繁体   English

如何使用自定义帮助程序(把手)实现嵌套的每个循环

[英]How to implement nested each loops with custom helpers (handlebar)

I am trying to build a table together with Ember.js and Handlebar.js. 我正在尝试与Ember.js和Handlebar.js一起建立表格。 Unfortunately I got stuck at the way how to build the cells which consist of Ember.TextArea with valueBinding. 不幸的是,我陷入了如何构建带有valueBinding的由Ember.TextArea组成的单元的方式。

The idea is the following. 这个想法如下。 There is domain model project which has many entries (1 to n relation). 有一个领域模型项目,其中有很多条目(1到n的关系)。 Both domain models are different object and are not embedded (the entries are not embedded in the project). 两个域模型都是不同的对象,并且没有嵌入(条目未嵌入到项目中)。

Every project has an array called keys which contains several strings (eg 'a', 'b', 'c', ...). 每个项目都有一个称为键的数组,其中包含多个字符串(例如'a','b','c',...)。 Furthermore every entry contains an array of elements. 此外,每个条目都包含一个元素数组。 Each of this element has also one of the above mentioned keys as a property key. 每个元素还具有上述键之一作为属性键。 See the detailed model below. 请参阅下面的详细模型。

Models 楷模

Project 项目

{ keys: ['a', 'b', 'c'] }

Entries 参赛作品

{
  parameters: [
    {
      key: 'a',
      value: 'aaaa'
    },
    {
      key: 'b',
      value: null
    },   
    {
      key: 'c',
      value: '123'
    }
  ]
}

The target is to have in the end a HTML table which contains a column for each key of the project (in the above mentioned case there would be 3 columns with headers 'a', 'b', 'c'). 目标是最终具有一个HTML表,该表包含一个用于项目的每个键的列(在上述情况下,将有3列带有标题“ a”,“ b”,“ c”)。 For every entry that is now associated to the project (in other words loaded in the background into an ArrayController), there must be a row. 对于现在与项目关联的每个条目(换言之,在后台加载到ArrayController中),必须有一行。 And here comes now the tricky part: Each cell must be bound to the appropriate element of the 'parameters' array (the content of the cell should be an Ember.TextArea). 接下来是棘手的部分:每个单元格必须绑定到“参数”数组的适当元素(单元格的内容应该是Ember.TextArea)。

|| a                                                             || b  || c ||
-----------------------------------------------------------------------------
| entry 1 binding to element of parameters array where key = 'a' | ... | ... |
----------------------------------------------------------------------------
| entry 2 binding to element of parameters array where key = 'a' | ... | ... |
-----------------------------------------------------------------------------

Approach I 方法一

Building the table headers is obviously pretty easy and works of course without any issue: 构建表头显然很容易,并且可以正常工作:

<table>
   <thead>
     <tr>
       {{#each key in project.keys}}
         <th>{{key}}</th>
       {{/each}}
     </tr>
   </thead>

   <tbody>
     ...
   <tbody>
</table>

The part where I don't know how to build the code is the body. 我不知道如何构建代码的部分是主体。 Iterating over the entries in the array controller possible yes, but how to bind then to the appropriate element - I have no clue. 遍历数组控制器中的条目是可能的,但是如何将其绑定到适当的元素-我不知道。 The tricky thing is, that the binding is established to the right element. 棘手的是,绑定建立在正确的元素上。 For example in the column for the key 'a', the binding must be to the element of the parameters array where element.key === 'a'. 例如,在键“ a”的列中,绑定必须绑定到参数数组的元素,其中element.key ==='a'。

<tbody>
  {{#each entry in App.entriesController}}
    <tr>
      {{#each key in project.keys}}
        ???
      {{/each}}
    </tr>
  {{/each}}
</tbody>

I thought of using a handlebar helper but figured out that Ember.js does (which is different than the documentation of handlebar.js) not pass the object itself, it only passes the name of the property which one can then use to get the value. 我曾考虑使用车把帮助器,但发现Ember.js确实(与handlebar.js的文档不同)没有传递对象本身,它仅传递了属性名称,然后可以使用该属性名称获取值。 Unfortunately for an array I do not see how to get the entry of the array that gets currently processed in the each loop. 不幸的是,对于数组,我看不到如何获取每个循环中当前正在处理的数组的条目。

The idea was to pass the entry and the key to the helper and this one then returns an instance of the Ember.TextArea which is bound to the correct element of the entry.parameters array. 想法是将条目和键传递给帮助程序,然后该键返回Ember.TextArea的一个实例,该实例绑定到entry.parameters数组的正确元素。

Note: By iterating over the project.keys we can guarantee that the order of the keys is the same as in the header (same iteration order). 注意:通过迭代project.keys,我们可以确保键的顺序与标题中的顺序相同(相同的迭代顺序)。

Any other ideas how to approach this issue? 还有其他想法如何解决这个问题?

The best solution here is to write a custom handlebars helper. 最好的解决方案是编写自定义车把助手。 Unfortunately, right now it's not that easy to make your custom bound helpers. 不幸的是,现在使您的自定义绑定助手变得不那么容易。 There's an old PR here that we'd like to update and get working for 1.0 https://github.com/emberjs/ember.js/pull/615 . 这里有一个旧的PR,我们想要更新并开始使用1.0 https://github.com/emberjs/ember.js/pull/615 You might be able to get some ideas from this to do your own implementation. 您也许可以从中得到一些想法来进行自己的实现。

crazy bathtub idea: You could use an Ember.Object as a Proxy, dynamically defining linearized properties on it (in Coffeescript for sanity, names just from braindump): 疯狂浴缸的主意:您可以使用Ember.Object作为代理,在其上动态定义线性化的属性(在Coffeescript中,出于理智,名称仅取自Braindump):

    TheProxy = Ember.Object.extend
      fill: (projects, entries) ->
         for project in projects
           entry = # find entry for project
           for key,value of entry
             this.set "value_for_#{project.id}_#{key}", value

After that, you could generate the template in a similar fashion, by generating the {{value_for_xxx_yyyy}} bindings and bind a filled instance of TheProxy to it. 之后,可以通过生成{{value_for_xxx_yyyy}}绑定并将TheProxy的填充实例绑定到模板来以类似的方式生成模板。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM