Discourse的创始人之一在他的博客http://eviltrout.com/2013/02/27/adding-to-discourse-part-1.html上发布了一个条目,解释他如何在Ember中进行ajax查询(而不是使用Ember数据)。如果用户导航到路线,它将触发找到的方法
路线
Discourse.AdminReportsRoute = Discourse.Route.extend({
model: function(params) {
return(Discourse.Report.find(params.type));
},
查找方法
Discourse.Report.reopenClass({
find: function(type) {
var model = Discourse.Report.create();
jQuery.ajax("/admin/reports/" + type, {
type: 'GET',
success: function(json) {
model.mergeAttributes(json.report);
model.set('loaded', true);
},
});
return(model);
}
});
我使用不同的示例使用此工作,但是,在成功回调中,我收到此错误消息
Uncaught TypeError: Object [object Object] has no method 'mergeAttributes'
由于我没有设置话语,我创建了一个不同的域模型
App.Restaurant = Ember.Object.extend({});
App.Restaurant.reopenClass({
find: function(type) {
var model = App.Restaurant.create();
jQuery.ajax("restaurants/",{
type: 'GET',
success: function(json) {
console.log(json);
model.mergeAttributes(json.restaurants);
model.set('loaded', true);
},
});
return(model);
}
});
在成功回调中记录json显示了这个
Object {restaurants: Array[28]}
restaurants: Array[28]
__proto__: Object
为什么我的模型上没有定义mergeAttributes?
我试图删除model.mergeAttributes,然后执行
success: function(json) {
model.set('loaded', true);
},
我收到此错误
Assertion failed: The value that #each loops over must be an Array. You passed <App.Restaurant:ember322>
所以如果我不能做mergeAttributes,有没有办法让成功回调中的数据返回一个数组?
{{#if loaded}}
<ul>
{{#each item in model}}
<li>{{item}}</li>
{{/each}}
</ul>
{{else}}
{{ loading}}
{{/if}}
-
model: function(params) {
return(App.Restaurant.findAll(params));
},
renderTemplate: function() {
this.render('restaurants', {into: 'application'});
}
答案 0 :(得分:2)
有一些问题:
首先,mergeAttributes
没有内置于Ember中。这是Discourse在Discourse.Model
中定义的东西,它是他们使用的模型基类。定义如下:https://github.com/discourse/discourse/blob/master/app/assets/javascripts/discourse/models/model.js#L12-L38
第二个问题是,在您的App.Restaurant.find
电话中,您正在获取餐馆列表,然后创建单个模型并将其返回。因此,传递给each
帮助器的对象只是一个App.Restaurant
对象而不是数组。这就是您粘贴的Assertion failed
错误所指的内容。
要完成您想要的任务,您应该执行以下操作:
App.Restaurant.reopenClass({
findAll: function() {
jQuery.getJSON("restaurants").then(function(json) {
return json.restaurants.map(function(attrs) {
return App.Restaurant.create(attrs);
});
});
}
});