将对象模型作为单个对象传递给ArrayController

问题描述:

我有一个起始页面,要求用户输入apiKey。使用该表单数据,我将其传递给我的deals路由,然后根据输入的apiKey获取相关数据。将对象模型作为单个对象传递给ArrayController

我的问题是,当我直接与URI的apiKey加载交易页面,它从形式start页面上会并与apiKey提交的时候,我收到以下错误工作正常,但是,:

Uncaught Error: assertion failed: an Ember.CollectionView's content must implement Ember.Array. You passed 'asdf' 

这里是app.js:

App = Ember.Application.create(); 

App.Store = DS.Store.extend({ 
    revision: 12, 
    adapter: 'DS.FixtureAdapter' 
}); 

App.Deal = DS.Model.extend({ 
    name: DS.attr('string') 
}); 

App.Deal.FIXTURES = [ 
    {id: 1, name: 'Deal 1'}, 
    {id: 2, name: 'Deal 2'} 
] 

App.Router.map(function() { 
    this.resource('start', { path: '/' }); 
    this.resource('deals', { path: '/deals/:api_key' }); 
}); 

App.StartController = Ember.ObjectController.extend({ 
    apiKey: '', 
    getDeals: function (model) { 
    this.transitionToRoute('deals', this.apiKey); 
    } 
}); 

App.DealsRoute = Ember.Route.extend({ 
    model: function() { 
    // return App.Deal.getWonFor(params.api_key); 
    return App.Deal.find(); 
    } 
}); 

App.DealController = Ember.ArrayController.extend({ 
}); 

App.DealsView = Ember.View.extend({ 
    didInsertElement: function() { 
    // Add active class to first item 
    this.$().find('.item').first().addClass('active'); 
    this.$().find('.carousel').carousel({interval: 1000}); 
    } 
}); 

下面是HTML:

<script type="text/x-handlebars"> 
    <h2>Won Deal Ticker</h2> 
    {{outlet}} 
    </script> 

    <script type="text/x-handlebars" data-template-name="start"> 
    {{view Em.TextField valueBinding="apiKey" placeholder="API Key" action="getDeals" }} 
    <br /> 
    <button {{action 'getDeals' apiKey}} class="btn btn-large">Get Won Deals!</button> 
    </script> 

    <script type="text/x-handlebars" data-template-name="deals"> 
    <div id="carousel" class="carousel slide"> 
     <div class="carousel-inner"> 
     {{#each model}} 
      <div class="item"> 
      {{name}} 
      </div> 
     {{/each}} 
     </div> 
    </div> 
    </script> 
+0

你从控制台发布相同的错误信息?我看不到“asdf”来自 – MilkyWayJoe 2013-04-10 01:14:18

+0

是的。 'start'视图包含一个TextField,我使用'apiKey'键入“asdf”并使用它下面的按钮进行提交。 – brandonhilkert 2013-04-10 01:48:04

这里的问题是,当您向Route#transitionTo传递第二个参数时,Ember.js会假定您传递模型并将其设置为控制器的模型,而不是使用model钩子。

的问题是在这里:

this.transitionToRoute('deals', this.apiKey); 

现在Ember.js认为,this.apiKey是你的路由模式,将跳过呼叫路由的model钩直接设置你的控制器的模型通过。

我能想到的解决此2种方式:

方法1(首选)

您可以创建一个新的资源用来包装deals资源:

this.resource('api', { path: '/:api_key' }, function() { 
    this.resource('deals'); 
}); 

然后:

App.ApiRoute = Ember.Route.extend({ 
    model: function(params) { 
    return params.api_key; 
    } 
}); 

App.DealsRoute = Ember.Route.extend({ 
    model: function() { 
    return App.Deal.getWonFor(this.modelFor('api')); 
    } 
}); 

和:

getDeals: function() { 
    this.transitionToRoute('deals', this.apiKey); 
} 

方法2

下面这是一个快速的解决方法(可能不是最优的),但应该工作:

getDeals: function() { 
    var router = this.get('target'), 
     url = '/deals/' + this.apiKey; 

    Ember.run.once(function() { 
    router.get('location').setURL(url); 
    router.notifyPropertyChange('url'); 
    }); 

    this.router.router.handleURL(url); 
} 
+0

这太棒了。我实施了“方法1”,效果很好。我试图围绕为什么它的工作。因此,由于我们为交易创建了单独的资源,因此可以按预期的方式将Array设置为Array,并将API资源保留为普通对象资源? – brandonhilkert 2013-04-10 10:50:51

+0

是的,我们现在有2个资源:'api' - >'api_key'和'posts' - >帖子数组,因为它嵌套在'api'资源中,所以'posts'资源不能存在。 – 2013-04-10 11:00:17

+0

感谢您的帮助!有太多的约定(这很好),但我仍然试图将自己的头脑和最佳实践自动创建。 – brandonhilkert 2013-04-10 11:01:30