使用Fixture Adapter在Ember.js中通过索引获取对象

时间:2014-05-20 21:38:42

标签: ember.js handlebars.js

这一直让我疯狂。我已经创建了一个翻转游戏,它将在硬件商店中安装。

我为我的路线设置了我的模型以获得我使用灯具适配器设置的所有“hwstores”:

window.FlipGame = Ember.Application.create({
  LOG_TRANSITIONS: true,
  LOG_TRANSITIONS_INTERNAL: true
});

FlipGame.ApplicationAdapter = DS.FixtureAdapter;

FlipGame.Hwstore = DS.Model.extend({
  number: DS.attr('string'),
  score: DS.attr('number'),
  city: DS.attr('string'),
  country: DS.attr('string')
});

FlipGame.Hwstore.FIXTURES = [
  { id: 1, number: 1234, score: 1000, city: 'Houston', country: 'USA' },
  { id: 2, number: 4321, score: 2000, city: 'Miami', country: 'USA' },
  { id: 3, number: 9999, score: 9999, city: 'Portland', country: 'USA' }
];


FlipGame.WelcomeRoute = Ember.Route.extend({
  model: function(controller){
    return this.store.find('hwstore');
  }
});

最终目标是获得得分最高的前三名商店。

我正在使用chrome的ember扩展,所以我可以看到我的所有三个对象都在我视图中的“模型”对象中。但是出于一些令人难以置信的愚蠢原因,我只能使用“firstObject”和“lastObject”来获取第一个和最后一个对象。没有办法获得中间对象。我已经尝试了我能想到的每种语法。

这有效:

<p class="lead">Store {{firstObject.number}}</p>
<p class="lead">{{firstObject.city}}, {{firstObject.country}}</p>
<p class="score"><strong>{{firstObject.score}}</strong></p>

这也有效:

<p class="lead">Store {{lastObject.number}}</p>
<p class="lead">{{lastObject.city}}, {{lastObject.country}}</p>
<p class="score"><strong>{{lastObject.score}}</strong></p>

这些都不起作用:

<p class="lead">Store {{objectAt(1).number}}</p>
<p class="lead">{{objectAt(1).city}}, {{objectAt(1).country}}</p>
<p class="score"><strong>{{objectAt(1).score}}</strong></p>

<p class="lead">Store {{[1].number}}</p>
<p class="lead">{{[1].city}}, {{[1].country}}</p>
<p class="score"><strong>{{[1].score}}</strong></p>

<p class="lead">Store {{this.model.[1].number}}</p>
<p class="lead">{{this.model.[1].city}}, {{this.model.[1].country}}</p>
<p class="score"><strong>{{this.model.[1].score}}</strong></p>

<p class="lead">Store {{model.objectAt(1).number}}</p>
<p class="lead">{{model.objectAt(1).city}}, {{model.objectAt(1).country}}</p>
<p class="score"><strong>{{model.objectAt(1).score}}</strong></p>

在您回答之前,请注意我无法使用{{#each}} {{/ each}}语法,因为每个商店的标记将彼此截然不同,并且需要在不同的顺序。

这里有一个非常类似的堆栈问题:How to get object at index in Array Controller within view?

但是,它没有回答我的问题。这些建议都不起作用。

此外,Chrome的ember扩展程序显示“模型”对象类型为:

<DS.RecordArray:ember356>

还有一种特殊方法可以在控制台中检查对象。真正激怒我的是,在控制台中,我可以这样做($ E是我对象的临时变量名):

$E.objectAt(1).get('number')

它工作正常!如果我在模板中尝试相同的事情:

{{this.model.objectAt(1).get('number')}}

它不会编译。

1 个答案:

答案 0 :(得分:2)

就我个人而言,我认为很少有人知道数组中的某个项目有点独特。一般情况下,用例是第一个/最后一个项目是特殊的,你可能对它有所了解。即使需要以不同方式呈现项目,您通常也会从模型上的某些属性中确定这一点并执行类似

的操作
{{#each item in controller}}
  {{#if item.isColor}}
    {{render 'color' item}}
  {{/if}}
  {{#if item.isDuck}}
     {{render 'duck' item}}
  {{/if}}
{{/each}}

但是在你的情况下,如果有前三项,并且你知道每一项都是特殊的,那么最简单的方法就是在你的控制器中添加一个计算属性

App.WelcomeController = Em.ArrayController.extend({
  secondObject: function(){
    return this.objectAt(1);
  }.property('model.[]')
});

这显然假设至少有2个对象,但是在welcome模板中,您可以将所有内容称为firstObjectsecondObjectlastObject

<p class="lead">Store {{secondObject.number}}</p>
<p class="lead">{{secondObject.city}}, {{secondObject.country}}</p>
<p class="score"><strong>{{secondObject.score}}</strong></p>

或者您可以享受更多乐趣:

App.WelcomeController = Em.ArrayController.extend({

  first: function(){
    return this.objectAt(0);
  }.property('model.[]'),

  second: function(){
    return this.objectAt(1);
  }.property('model.[]'),

  third: function(){
    return this.objectAt(2);
  }.property('model.[]')
});