Где мои данные застряли в Ember? <! ---->
Я пытаюсь выучить ember, но мне трудно понять, почему мои данные из бэкэнда не отображаются. Я использую Ember Data с приборами Mirage. Данные отображаются. Только если я ввожу простые отношения, данные из этих отношений не отображаются в моем приложении. Есть ли общий способ отладки, когда вы просто получаете <!---->
в вашем приложении ember?
mirage/fixtures/contacts.js
export default [
{
id: 1,
userName: "Barack Obama",
profilePictureUrl: "/img/profilepics/barack.png",
conversation: 1
},
];
mirage/fixtures/conversations.js
export default [
{
id: 1,
contact: 1,
lastConversationTime: 'Sun Jun 07 2015 14:05:50 GMT+0200 (CEST)',
},
];
mirage/config.js
export default function() {
this.get('/api/conversations');
this.get('/api/conversations/:id');
this.get('/api/contacts');
this.get('/api/contacts/:id');
}
App = Ember.Application.create();
App.Router.map(function() {
// put your routes here
this.route('contacts');
this.route('conversations');
});
App.ContactsRoute = Ember.Route.extend({
model: function() {
return this.store.find('contact');
}
});
App.ConversationsRoute = Ember.Route.extend({
model: function() {
return this.store.find('conversation');
}
});
App.ContactModel = DS.Model.extend({
userName: DS.attr('string'),
profilePictureUrl: DS.attr('string'),
conversation: DS.belongsTo('conversation'),
});
App.ConversationModel = DS.Model.extend({
lastConversationTime: DS.attr('date'),
contact: DS.belongsTo('contact')
});
$.mockjax({
url: "/contacts",
type: "GET",
status: 200,
statusText: "OK",
responseText: {
contacts: [{
id: 1,
userName: "Barack Obama",
profilePictureUrl:"/img/profilepics/barack.png",
conversation: 1
}]
}
});
$.mockjax({
url: "/conversations",
type: "GET",
status: 200,
statusText: "OK",
responseText: {
conversations: [{
id: 1,
contact: 1,
lastConversationTime: 'Sun Jun 07 2015 14:05:50'
}]
}
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Ember Starter Kit</title>
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/normalize/3.0.1/normalize.css">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://builds.emberjs.com/tags/v1.11.1/ember-template-compiler.js"></script>
<script src="http://builds.emberjs.com/tags/v1.11.1/ember.debug.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/ember-data.js/1.0.0-beta.16.1/ember-data.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery-mockjax/1.5.3/jquery.mockjax.js"></script>
</head>
<body>
<script type="text/x-handlebars">
<h2>Welcome to Ember.js</h2>
{{link-to 'contacts' 'contacts'}}
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="contacts">
<ul>
{{#each model as |contact|}}
<li>{{contact.userName}}</li>
<li>{{conversation.lastConversationTime}}</li>
{{/each}}
</ul>
</script>
</body>
</html>
Ember: 1.12.1 Ember Data: 1.0.0-beta.19 jQuery: 1.11.3
Это JSBin, который воспроизводит проблему: http://emberjs.jsbin.com/deledemaya/1/edit?html,js,output
1 ответ
Глядя на пример JSBin.
У вас есть ряд проблем в вашем коде.
Прежде всего, в вашем шаблоне вы получаете доступ к conversation
модель как это:
<ul>
{{#each model as |contact|}}
<li>{{contact.userName}}</li>
<li>{{conversation.lastConversationTime}}</li>
{{/each}}
</ul>
conversation
нигде не определено. Как conversation
это отношения на contact
, вы должны получить к нему доступ через contact
как это:
<li>{{contact.conversation.lastConversationTime}}</li>
Обратите внимание, что вам не нужно conversation
маршрут, определенный для доступа к разговору через контакт в contact
маршрут.
Затем принято называть модели App.Foo
и не App.FooModel
, Эта информация полезна только в JSBins, так как современные приложения Ember не используют глобальные переменные (App
).
Наконец, ваша главная ошибка в том, что вы определили свои отношения как синхронные. Связи синхронизации предполагают, что все запрошенные связанные записи уже доступны в магазине. Чтобы достичь этого, вы должны загрузить связанные данные следующим образом:
$.mockjax({
url: "/contacts",
type: "GET",
status: 200,
statusText: "OK",
responseText: {
contacts: [{
id: 1,
userName: "Barack Obama",
profilePictureUrl:"/img/profilepics/barack.png",
conversation: 1
}],
conversations: [{
id: 1,
contact: 1,
lastConversationTime: 'Sun Jun 07 2015 14:05:50'
}]
}
});
Демонстрация: http://emberjs.jsbin.com/taboge/1/edit?html,js,output
Кроме того, вы можете определить свои отношения как асинхронные. Это скажет Ember извлекать записи из бэкэнда всякий раз, когда он сталкивается с отсутствующими отношениями.
Пример:
App.Contact = DS.Model.extend({
userName: DS.attr('string'),
profilePictureUrl: DS.attr('string'),
conversation: DS.belongsTo('conversation', {async: true}),
});
$.mockjax({
url: "/contacts",
type: "GET",
status: 200,
statusText: "OK",
responseText: {
contacts: [{
id: 1,
userName: "Barack Obama",
profilePictureUrl:"/img/profilepics/barack.png",
conversation: 1
}]
}
});
$.mockjax({
url: "/conversations/1",
type: "GET",
status: 200,
statusText: "OK",
responseText: {
conversation: {
id: 1,
contact: 1,
lastConversationTime: 'Sun Jun 07 2015 14:05:50'
}
}
});
Демонстрация: http://emberjs.jsbin.com/qejayi/1/edit?html,js,output
Асинхронные отношения заставляют вас работать с ними через обещания.
Также обратите внимание, что вам не нужно определять оба направления отношений как асинхронные. На самом деле, вам не нужны обратные отношения вообще! Обратные отношения нужны только в том случае, если вы хотите получить пользователей для данного разговора.
И имейте в виду, что в настоящее время Ember очень хочет запрашивать асинхронно связанные записи. Если вы запрашиваете только идентификатор связанной записи, Ember извлечет всю запись, даже если в этом нет необходимости: идентификатор уже известен. Я надеюсь, что эта проблема будет решена в одном из следующих выпусков Ember Data.