2013-09-08 3 views
1

Один из основателей Discourse опубликовал запись в своем блоге http://eviltrout.com/2013/02/27/adding-to-discourse-part-1.html, объясняющую, как он делает запросы ajax в Ember (в отличие от использования данных Ember). Если пользователь переходит к маршруту будет вызывать найденную методуотображение данных после вызова ajax в Ember

Route

Discourse.AdminReportsRoute = Discourse.Route.extend({ 
    model: function(params) { 
     return(Discourse.Report.find(params.type)); 
     }, 

метод Find

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' 

Поскольку у меня не было дискурса, я создал ди fferent модель предметной области

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'}); 
    } 

ответ

2

Есть несколько проблем:

Во-первых, mergeAttributes не встроены в Эмбер. Это то, что 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); 
     }); 
    }); 
    } 
}); 
+0

Спасибо так много. В соответствии с консолью теперь работает ajax (и я чему-то научился :), но это не превращение в шаблон так, как я вызываю метод (см. Нижнюю часть OP для того, как я его вызываю и пытаюсь отобразить). Если вы можете добавить немного более подробно, я бы очень признателен. Заранее спасибо. – Leahcim

+0

Возможно, это не рендеринг, потому что обратный вызов не устанавливает 'загружен' в возвращаемый массив модели. Как в стороне, этот шаблон (возвращая модель сразу и используя загруженные флаги, чтобы проверить, нужно ли делать рендер) в наши дни не так распространен в Ember.Причина в том, что в последних версиях маршрутизатора, если «модельный» крючок возвращает обещание, переход приостанавливается до тех пор, пока не будет достигнуто обещание. В результате шаблон не будет отображаться до тех пор, пока данные модели не будут доступны, поэтому защита не нужна. Во всяком случае, я просто догадываюсь. Если это не сработает, опубликуйте jsbin, и я буду комментировать дальше. –

+0

Я удалил чек для 'загруженных' из шаблонов, и он все еще не работает. Вот jsbin, показывающий, что я делаю, хотя я не уверен, как заставить его работать без данных сервера. Http://jsbin.com/EvOmEfe/5/edit Возможно, вы все еще можете видеть, что я делаю неправильно. – Leahcim