Ember.js - Как правильно связать коллекцию с представлением, используя Ember.Router?
Я ранее работал с Ember.StateManager
и теперь я делаю некоторые тесты, прежде чем наконец переключиться на Ember.Router
, но я не понимаю, как правильно связать данные моего вида из коллекции, находящейся в моем контроллере.
У меня очень простая структура тестирования с Ember.Router
которая работает нормально с навигацией, но когда дело доходит до привязки данных, она работает не так, как ожидалось, и я признаюсь, что сейчас потерян. Что касается моих данных, у меня есть простой веб-API ASP.NET MVC4, на котором работает служба REST, которая работает нормально (я проверил с Fiddler, и все это хорошо). Хранение в SQL с EF4.* И никаких проблем там нет.
Что касается клиентского приложения, в моем contacts.index
маршрут, я попытался связать его в connectOutlets
(я должен делать это другим методом?), но мой код, кажется, не работает правильно, так как мое представление никогда не ограничено.
Что я пробовал раньше, в connectOutlets
метод contacts.index
маршрут:
1
router.get('applicationController').connectOutlet('contact');
2
router.get('applicationController').connectOutlet(
'contact',
router.get('contactController').findAll()
);
Я также пытался использовать enter
метод с
this.setPath('view.contacts', router.get('contactController').content);
И я попытался связать это непосредственно в представлении как:
App.ContactView = Ember.View.extend({
templateName: 'contact-table'
contactsBinding: 'App.ContactController.content'
});
Вот текущая версия моего кода:
var App = null;
$(function () {
App = Ember.Application.create();
App.ApplicationController = ...
App.ApplicationView = ...
App.HomeController = ...
App.HomeView = ...
App.NavbarController = ...
App.NavbarView = ...
App.ContactModel = Ember.Object.extend({
id: null,
firstName: null,
lastName: null,
email: null,
fullName: function () {
return '%@ %@'.fmt(this.firstName, this.lastName)
}.property('firstName', 'lastName')
});
App.ContactController = Ember.ArrayController.extend({
content: [],
resourceUrl: '/api/contact/%@',
isLoaded: null,
findAll: function () {
_self = this;
$.ajax({
url: this.resourceUrl.fmt(''),
type: 'GET',
contentType: 'application/json; charset=utf-8',
success: function (data) {
$(data).each(function () {
_self.pushObject(App.ContactModel.create({
id: this.Id,
firstName: this.FirstName,
lastNaem: this.LastName,
email: this.Email
}));
});
alert(_self.get('content').length);
// this alerts 6 which is the same number of
// records in my database, and if I inspect
// the content collection in chrome, I see my data
// that means the problem is not the ajax call
},
error: function (xhr, text, error) {
alert(text);
}
});
},
find: function (id) {
// GET implementation
},
update: function (id, contact) {
// PUT implementation
},
add: function (contact) {
// POST implementation
},
remove: function(id) {
// DELETE implementation
}
});
App.ContactView = Ember.View.extend({
templateName: 'contact-table'
});
App.ContactListItemView = Ember.View.extend({
templateName: 'contact-table-row'
});
App.Router = Ember.Router.extend({
enableLogging: true,
location: 'hash',
root: Ember.Route.extend({
// actions
gotoHome: Ember.Route.transitionTo('home'),
gotoContacts: Ember.Route.transitionTo('contacts.index'),
// routes
home: Ember.Route.extend({
route: '/',
connectOutlets: function (router, context) {
router.get('applicationController').connectOutlet('home');
}
}),
contacts: Ember.Route.extend({
route: '/contacts',
index: Ember.Route.extend({
_self: this,
route: '/',
connectOutlets: function (router, context) {
router.get('contactController').findAll();
router.get('applicationController').connectOutlet('contact');
router.get('contactView').set('contacts', router.get('contactController').content);
// if I inspect the content collection here, it's empty, ALWAYS
// but if I access the same route, the controller will alert
// the number of items in my content collection
}
})
})
})
});
App.initialize();
});
Вот соответствующие шаблоны:
<script type="text/x-handlebars" data-template-name="contact-table">
<table>
<thead>
<tr>
<th>Name</th>
<th>Email</th>
</tr>
</thead>
<tbody>
{{#if contacts}}
{{#each contact in contacts}}
{{view App.ContactListItemView contactBinding="contact"}}
{{/each}}
{{else}}
<tr>
<td colspan="2">
You have no contacts <br />
:(
<td>
</tr>
{{/if}}
</tbody>
</table>
</script>
<script type="text/x-handlebars" data-template-name="contact-table-row">
<tr>
<td>
{{contact.fullName}}
</td>
<td>
e-mail: {{contact.email}}
</td>
</tr>
</script>
В качестве теста я также попытался вручную заполнить content
коллекция в моем контроллере, как показано ниже, но, опять же, он был пуст, когда я перешел на этот маршрут:
App.ContactController = Ember.ArrayController.extend({
content: [],
init: function() {
this._super();
this.pushObject(
App.ContactModel.create({ ... })
);
}
})
Хорошо, если вам удастся прочитать до сих пор, вот мой вопрос: как правильно связать коллекцию с представлением, используя Ember.Router?
Я видел ряд примеров, а также другие вопросы в SO, и я еще не видел ничего, что бы работало для меня (не стесняйтесь указывать другие примеры с привязкой)
Спасибо
1 ответ
Привязка не работает, потому что "массив мутирует, но само свойство не меняется". /questions/33825767/v-emberjs-pochemu-privyazka-k-massivu-ne-rabotaet-za-predelami-each/33825771#33825771
Используя App.initialize и Ember.Router, представления и контроллеры теперь автоматически соединяются. Существует очень мало причин для ручного связывания контактов в вашем представлении с контентом контроллера, поскольку у вас уже есть доступ к нему.
Измените шаблон вашего представления, чтобы включить:
{{#if controller.isLoaded}} // set this true in your ajax success function
{{#each contact in controller}}
{{view App.ContactListItemView contactBinding="contact"}}
{/each}}
{{else}}
<tr>
<td colspan="2">
You have no contacts <br />
:(
<td>
</tr>
{{/if}}