为什么在插入{{#each}}块内的元素之前,didInsertElement会挂钩?

时间:2014-07-30 06:17:50

标签: ember.js

我是Ember的新手,我想在{{#each}}块的元素中添加一些查询DOM操作代码。所以我谷歌并找到this guide的解决方案:

视图/产品/ index.js

import Spinner from 'appkit/utils/someJqueryCode';

Ember.View.reopen({
  didInsertElement : function(){
    this._super();
    Ember.run.scheduleOnce('afterRender', this, this.afterRenderEvent);
  },
  afterRenderEvent : function(){
    // implement this hook in your own subclasses and run your jQuery logic there
  }
});

export default Ember.View.extend({
  afterRenderEvent: function() {
    Spinner();
  }
});

模板/产品/ index.hbs

<div class='panel panel-default products'>
    <div class='panel-heading'>
        <h2 class='panel-title'>Our Prodcuts</h2>
    </div>
    <div class='panel-body'>
        <ul class='row'>
        {{#each}}
            <li class='col-md-4'>
    <div class='thumbnail'>
        <img {{bind-attr src=url alt=alt}} />
    </div>
    <div class='caption'>
        <h3 class='name-me'>{{name}}</h3>
        <p>{{description}}</p>
        <div class='row no-gutter'>
            <div class='col-xs-3'>
                <button class='btn btn-primary'>Buy</button>
            </div>
        </div>
    </div>
</li>
        {{/each}}
      </li>
  </div>
</div>

但是我似乎在触发afterRenderEvent()之后,{{#each}}块中的所有元素都还没有呈现给DOM,因此,jQuery代码返回undefined

做正确的方法是什么?

1 个答案:

答案 0 :(得分:3)

一旦呈现应用程序路由,您的视图的didInsertElement挂钩就会触发,这发生在索引路由之前。您可能认为将它放在index.js文件中会起作用,但它只会扩展默认的应用程序视图行为。

您需要创建一个更有针对性的视图,该视图位于index.hbs文件中。一个只关注你的微调器jQuery doohickey。那个,每个/ else条件可以在这里很好地工作。例如:

{{#each}}
  {{#view App.SpinnerDoohickeyView}}
  <li class='col-md-4'>
    <div class='thumbnail'>
      <img {{bind-attr src=url alt=alt}} />
    </div>
    <div class='caption'>
      <h3 class='name-me'>{{name}}</h3>
      <p>{{description}}</p>
      <div class='row no-gutter'>
        <div class='col-xs-3'>
          <button class='btn btn-primary'>Buy</button>
        </div>
      </div>
    </div>
  </li>
  {{/view}}
{{else}}
  <li>Empty collection!</li>
{{/each}}

请注意,我已将每个列表项包装在自己的视图中。如果你想要,你可以包装整个ul ......这只是一个例子。我们的想法是,您只在拥有模型时创建视图。

现在你可以定义视图,只需使用didInsertElement钩子来处理jQuery:

App.SpinnerDoohickeyView = Ember.View.extend({
  didInsertElement: function () {
    this.$('li').css('background', 'blue');
  }
});

如果你有一个要渲染的模型,jQuery应该能够以这种方式安全地访问它。祝你好运!

这里有一些进一步的阅读和来自Ember人的一些代码,看起来像我在这里向你展示的那样:http://emberjs.com/guides/views/handling-events/