为什么#each遍历顺序在组件内部时会反转?

时间:2014-12-14 12:49:07

标签: ember.js

See the jsbin example here

这是我的代码:



App = Ember.Application.create();

App.Router.map(function() {
  // put your routes here
});

App.IndexRoute = Ember.Route.extend({
  model: function() {
    return ['red', 'yellow', 'blue'];
  }
});

App.DerpMenuComponent = Ember.Component.extend({
    items: null,
    createSteps: function() {
        this.set('items', Ember.ArrayProxy.create({content: []}));
    }.on('init'),
    register: function(item) {
        this.get('items').addObject(item);
    }
});

App.DerpMenuItemComponent = Ember.Component.extend({
    title: null,
    register: function() {
        this.get('parentView').register(this);
    }.on('didInsertElement')
});

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="http://builds.handlebarsjs.com.s3.amazonaws.com/handlebars-v1.3.0.js"></script>
<script src="http://builds.emberjs.com/tags/v1.8.0/ember.js"></script>

<script type="text/x-handlebars">
    <h2>Welcome to Ember.js</h2>

    {{outlet}}
</script>

<script type="text/x-handlebars" id="index">
    {{#derp-menu}}
      {{#each item in model}}
        {{#derp-menu-item title=item}}
          <div style="background: #CCC; color: #00F; margin: 10px; padding: 5px">{{item}}</div>
        {{/derp-menu-item}}
      {{/each}}
    {{/derp-menu}}
</script>

<script type="text/x-handlebars" id="components/derp-menu">
    <ul>
      {{#each item in items}}
        <li>{{item.title}}</li>
      {{/each}}
      {{yield}}
  </ul>
</script>

<script type="text/x-handlebars" id="components/derp-menu-item">
    {{yield}}
</script>
&#13;
&#13;
&#13;

我可以看到derp-menu-elements以相反的顺序注册,当使用#each帮助器将它们以语音方式添加到模板中时。任何人都可以解释为什么会这样吗?如果我在derp-menu-item组件中手动输入derp-menu - 所有内容都正确显示,我就会猜到这一点,因为在这种情况下,Handlebars会以某种方式采取不同的行为。任何人都可以提供有关这两种情况中发生的事情的见解吗?

1 个答案:

答案 0 :(得分:2)

didInsertElement事件始终从最后/最低级别触发,然后向上移动树。这样,当在父元素上触发didInsertElement时,您可以确保所有子元素都已插入到dom中。

在您的情况下,您正在向父.on('didInsertElement')注册,您最终将以相反的顺序添加到数组中。

如果您将代码更改为基于.on('init')(如下所示),那么它们将按照相同的顺序排列。

App.DerpMenuItemComponent = Ember.Component.extend({
    title: null,
    register: function() {
        this.get('parentView').register(this);
    }.on('init')
});

您可以在此处查看一个有效的示例:http://emberjs.jsbin.com/hirolu/1/edit?html,js,output