【问题标题】:Handlebars - Set ID of Object created with {{each}} HelperHandlebars - 设置使用 {{each}} Helper 创建的对象的 ID
【发布时间】:2013-05-07 06:49:37
【问题描述】:

假设我在一个列表中有许多对象,我想从这些对象中创建 <table/> 中的 <tr/> 元素。我像这样创建了一个Ember.View

App.TableRowItem = Ember.View.extend({
  classNames: ['list-row'],
  templateName: 'admin/things/tableRow',
  showActionRow: function() {},
  edit: function() {},
  save: function() {},
  delete: function() {}
});

现在,我想在 Handlebars 模板中为检索到的列表中的每个对象生成一个行项目,如下所示:

<table id="someTable">
  <thead>
    <tr><th>Head1</th><th>Head2</th><th>Head3</th></tr>
  </thead>
  <tbody>
    {{# each thing in controller.things}}
      {{log thing}}
      {{view App.TableRowItem contentBinding="thing" id="thing.id"}}
    {{/each}}
  </tbody>
</table>

我希望它能够为每个 id 为 this.id 的元素创建一个 id 标记,但我收到以下错误消息:

Uncaught Error: assertion failed: Attempted to register a view with an id already in use: this.id

我做错了什么?如果我没有在{{view}} 助手中设置id,我会收到与上面相同的消息,但它抱怨id already in use: null...


更新:

由于我无法使用 idBinding 解决问题,我在 App.TableRowItem 视图中尝试了以下解决方案:

App.TableRowItem = Ember.View.extend({
  tagName: 'tr',
  templateName: 'admin/things/tableRow',

  // this is new!
  init: function() {
    var text = "";
    var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

    for( var i=0; i < 5; i++ ) {
      text += possible.charAt(Math.floor(Math.random() * possible.length));
    }

    this.set('elementId', text);
  }
});

现在我没有看到任何错误,但我看到模板中不仅有 &lt;tr/&gt; (admin/things/tableRow),而且还有一个 &lt;div/&gt; 元素,它似乎代表了我的 @ 987654338@没有任何内容!?

虽然调试 this.$() 给了我一个空的 &lt;tr id="1fFxV" class="ember-view"&gt;&lt;/tr&gt; 并且 tableRow 模板可以通过 this.$().closest('tr').next() 访问...

【问题讨论】:

    标签: ember.js handlebars.js


    【解决方案1】:

    如果您希望this 引用循环中的项目,您需要更改您的{{#each}} 格式:

    {{#each controller.things}}
      <!-- here the value of `this` is each item in the loop -->
    {{/each}}
    

    {{each}} 的构造方式,this 不是指项目,而是指控制器。

    {{#each thing in controller.things}}
      <!-- to reference every item you need to use `thing` instead of `this` -->
    {{/each}}
    

    这样就可以了:

    {{#each thing in controller.things}}
      {{view App.TableRowItem contentBinding="thing" idBinding="thing.id"}}
    {{/each}}
    

    或者这个:

    {{#each controller.things}}
      {{view App.TableRowItem contentBinding="this" idBinding="id"}}
    {{/each}}
    

    【讨论】:

    • 非常感谢您的解决方案!不幸的是,idBinding 似乎不起作用 - 我一遍又一遍地收到错误id already in use: null。只是为了清除问题:我什至不在乎元素有哪个id,我只想摆脱错误:)
    • 事情似乎变得比应有的复杂。这是一个可以帮助你的工作小提琴:jsfiddle.net/ztWEJ
    • 非常感谢您的提琴 - 我想我会按照这个方向去做,不会因为一张桌子而变得太复杂 :)
    【解决方案2】:

    我也做过类似的。我的控制器看起来像这样:

    App.ExampleController = Ember.ObjectController.extend({
      id: function() {
        var id = this.get('id');
        return id;
      }.property('id')
    });
    

    在我看来是这样的:

    {{#each item in items }}
      <div class="exampleItem" {{bindAttr id="item.id"}}>
        Code comes here..
      </div>
    {{/each}}
    

    希望对你有帮助!

    【讨论】:

      【解决方案3】:

      您是否检查过 HTML。我想你会发现你正在将 elementId 设置为字符串“this.id”,如果你想绑定值,你必须使用绑定。

      但是,如果您尝试使用 elementIdBinding="this.id",则会引发错误,因为一旦创建元素,就无法修改 id,因为 Ember 使用 ID 进行内部预订。

      几乎不值得尝试在集合中设置自定义 ID 并尝试在不需要特定 ID 的情况下解决您的问题

      【讨论】:

      • 非常感谢 - 事实上,我什至不关心 id,但如果我没有设置任何 ID,我会一直看到错误 ...id already in use: null...
      猜你喜欢
      • 1970-01-01
      • 2016-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-29
      • 1970-01-01
      • 2023-04-10
      • 1970-01-01
      相关资源
      最近更新 更多