I'm relatively new to Ember and JS frameworks and I'm facing difficulty in connecting a model to the Ember Table view/component.
With the code I currently have, the table is rendering but the rows are not being populated with any data. Obviously, I'm doing something wrong and falling short of understanding how to make this work properly. I have tried to implement something similar to the technique used here and here but can't get it to work.
I wanted to use the FixtureAdapter to populate the model with data for now but later on move to retrieving the data from my backend API via Ajax/JSON.
Any help is greatly appreciated.
The JS part:
window.App = Ember.Application.create({
LOG_TRANSITIONS: true,
LOG_TRANSITIONS_INTERNAL: true,
LOG_VIEW_LOOKUPS: true,
// LOG_ACTIVE_GENERATION: true,
LOG_BINDINGS: true
});
var stringAttr = DS.attr('string');
App.Item = DS.Model.extend({
name: stringAttr,
desc: stringAttr,
category: DS.attr('number'),
tags: stringAttr,
note: stringAttr
});
App.Item.FIXTURES = [
{ id: 0, name: 'XY Laptop', desc: 'test laptop', category: 1, tags: 'computers, laptops', note:"note"},
{ id: 1, name: 'ZZ Computer', desc: 'super computer!', category: 0, tags: 'computers', note:"note"},
{ id: 2, name: 'MM Radio', desc: 'FM Radio', category: 1, tags: 'radios, recorders', note:"note"}
];
App.Router.map(function() {
this.resource('inventory', function() {
this.resource('items', function() {
this.resource('item', { path: ':item_id' }, function() {
this.route('edit');
});
});
});
});
// Temporary buffer object that sites between Ember Table and the model object (the Item model object)
App.RowProxy = Ember.Object.extend({
object: null,
getObjectProperty: function(prop) {
var obj = this.get('object');
if(obj) { console.log(prop + " : " + obj.get(prop)); }
return obj ? obj.get(prop) : 'Loading ...';
},
isLoaded: function() { return !!this.get('object'); }.property('object'),
id: function() { return this.getObjectProperty('id'); }.property('object.id'),
name: function() { return this.getObjectProperty('name'); }.property('object.name'),
desc: function() { return this.getObjectProperty('desc'); }.property('object.desc'),
category: function() { return this.getObjectProperty('category'); }.property('object.category'),
tags: function() { return this.getObjectProperty('tags'); }.property('object.tags'),
note: function() { return this.getObjectProperty('note'); }.property('object.note')
});
App.LazyDataSource = Ember.ArrayProxy.extend({
requestPage: function(page) {
var content, end, start, url, _i, _results;
content = this.get('content');
start = (page - 1) * 3;
end = start + 3;
// find items and then update the RowProxy to hold the item object.
this.get('store').find('item').then(function(items) {
return items.forEach(function(item, index) {
var position = start + index;
content[position].set('object', item);
});
});
// fill the 'content' array with RowProxy objects
return (function() {
_results = [];
for (var _i = start; start <= end ? _i < end : _i > end; start <= end ? _i++ : _i--){ _results.push(_i); }
return _results;
}).apply(this).forEach(function(index) {
return content[index] = App.RowProxy.create({
index: index
});
});
},
objectAt: function(index) {
var content, row;
content = this.get('content');
row = content[index];
if (row && !row.get('error')) {
return row;
}
this.requestPage(Math.floor(index / 3 + 1));
return content[index];
}
});
App.ItemsController = Ember.Controller.extend({
hasHeader: false,
hasFooter: false,
rowHeight: 35,
numRows: 10,
store: null,
columns: Ember.computed(function() {
var columnNames, columns;
columnNames = ['Name','Desc','Category','Tags','Note'];
columns = columnNames.map(function(key, index) {
return Ember.Table.ColumnDefinition.create({
columnWidth: 150,
headerCellName: key.w(),
contentPath: key
});
});
return columns;
}).property(),
content: Ember.computed(function() {
return App.LazyDataSource.create({
content: new Array(this.get('numRows')),
store: this.get('store')
});
}).property('numRows')
});
While the requestPage method above is not strictly required now, it would be useful to use when I migrate to the RESTful API, I kept it.
The HTML template looks like this:
<script type="text/x-handlebars">
{{#link-to 'items'}}
<i class="icon-edit"></i>
Item Management
{{/link-to}}
<div class="page-content">
{{outlet}}
</div><!-- /.page-content -->
</script>
<script type="text/x-handlebars" data-template-name="items">
<div class="row">
{{table-component
columnsBinding="columns"
contentBinding="content"
}}
</div>
</script>
I wasn't too sure how to show the table but my attempt to define it via a View wasn't successful.
I'm using: