将对象模型作为单个对象传递给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>
这里的问题是,当您向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);
}
这太棒了。我实施了“方法1”,效果很好。我试图围绕为什么它的工作。因此,由于我们为交易创建了单独的资源,因此可以按预期的方式将Array设置为Array,并将API资源保留为普通对象资源? – brandonhilkert 2013-04-10 10:50:51
是的,我们现在有2个资源:'api' - >'api_key'和'posts' - >帖子数组,因为它嵌套在'api'资源中,所以'posts'资源不能存在。 – 2013-04-10 11:00:17
感谢您的帮助!有太多的约定(这很好),但我仍然试图将自己的头脑和最佳实践自动创建。 – brandonhilkert 2013-04-10 11:01:30
你从控制台发布相同的错误信息?我看不到“asdf”来自 – MilkyWayJoe 2013-04-10 01:14:18
是的。 'start'视图包含一个TextField,我使用'apiKey'键入“asdf”并使用它下面的按钮进行提交。 – brandonhilkert 2013-04-10 01:48:04