简体   繁体   中英

Combining Ember Table with Ember Data

I'm trying to use Ember Data to bind data to Ember Table and display a list of contacts. I'm basing my code off of this question but I still seem to be missing something. The table is created and populated with the proxy objects and the promise to fetch data is executed. I get back the JSON data I expect in the promise response, but it looks like the row proxy's object always remains null. Here's what I have so far (omitting some things like routes, etc.):

window.Crm = Ember.Application.create({
});

Crm.Store = DS.Store.extend({
    adapter: DS.RESTAdapter,
    url: 'http://mywebsiteurl.com'
});

Crm.Contact = DS.Model.extend({
    id: DS.attr('string'),
    prefix: DS.attr('string'),
    firstName: DS.attr('string'),
    middleName: DS.attr('string'),
    lastName: DS.attr('string'),
    suffix: DS.attr('string'),
    gender: DS.attr('string')
});

// contact table data source
Crm.ContactTableDataSource = Ember.ArrayProxy.extend({

    // fetch page of contacts
    requestPage: function (page) {
        var content = this.get('content'),
            store = this.get('store'),
            start = (page - 1) * 30,
            end = start + 30,
            _results = [];

        store.find(
            'contact', { page: page }).then(function (contacts) {
            return contacts.forEach(function (contact, index) {
                content[start + index].set('object', contact);
            });
        });

        return (function () {
            for (var _i = start; 
                    start <= end ? _i < end : _i > end; 
                    start <= end ? _i++ : _i--
            ) {
                _results.push(_i); 
            }
            return _results;
        }).apply(this).forEach(function (index) {
            content[index] = Crm.ContactRowProxy.create({
                index: index
            });
            return content[index];
        });
    },

    objectAt: function (index) {
        var content = this.get('content'),
            row = content[index];

        if (row && !row.get('error')) {
            return row;
        }

        this.requestPage(Math.floor(index / 30 + 1));
        return content[index];
    }
});

// a proxy row that sits in between the table and server response
Crm.ContactRowProxy = Ember.Object.extend({

    object: null,

    getObjectProperty: function (property) {
        var obj = this.get('object');
        return obj ? obj.get(property) : '...';
    },

    isLoaded: function () {
        return this.get('object') !== undefined;
    }.property('object'),

    id: function () {
        return this.getObjectProperty('id');
    }.property('object.id'),

    prefix: function () {
        return this.getObjectProperty('prefix');
    }.property('object.prefix'),

    firstName: function () {
        return this.getObjectProperty('firstName');
    }.property('object.firstName'),

    middleName: function () {
        return this.getObjectProperty('middleName');
    }.property('object.middleName'),

    lastName: function () {
        return this.getObjectProperty('lastName');
    }.property('object.lastName'),

    suffix: function () {
        return this.getObjectProperty('suffix');
    }.property('object.suffix'),

    gender: function () {
        return this.getObjectProperty('gender');
    }.property('object.gender')

});

Crm.ContactsController = Ember.Table.TableContainer.extend({

    numRows: 30,

    columns: Ember.computed(function () {
        var id, prefix, firstName, middleName, lastName, suffix, gender;

        id = Ember.Table.ColumnDefinition.create({
            columnWidth: 50,
            contentPath: 'id',
            isSortable: false,
            isResizable: false,
            canAutoResize: false,
            tableCellViewClass: 'Crm.ContactCheckboxTableCell'
        });

        prefix = Ember.Table.ColumnDefinition.create({
            headerCellName: 'Prefix',
            getCellContent: function (row) {
                return row.get('prefix');
            },
            textAlign: 'text-align-left',
        });

        firstName = Ember.Table.ColumnDefinition.create({
            headerCellName: 'First Name',
            getCellContent: function (row) {
                return row.get('firstName');
            },
            textAlign: 'text-align-left'
        });

        middleName = Ember.Table.ColumnDefinition.create({
            headerCellName: 'Middle Name',
            getCellContent: function (row) {
                return row.get('middleName');
            },
            textAlign: 'text-align-left'
        });

        lastName = Ember.Table.ColumnDefinition.create({
            headerCellName: 'Last Name',
            getCellContent: function (row) {
                return row.get('lastName');
            },
            textAlign: 'text-align-left'
        });

        suffix = Ember.Table.ColumnDefinition.create({
            headerCellName: 'Suffix',
            getCellContent: function (row) {
                return row.get('suffix');
            },
            textAlign: 'text-align-left'
        });

        gender = Ember.Table.ColumnDefinition.create({
            headerCellName: 'Gender',
            getCellContent: function (row) {
                return row.get('gender');
            },
            textAlign: 'text-align-left'
        });

        return [id, prefix, firstName, middleName, lastName, suffix, gender];

    }).property(),

    content: Ember.computed(function () {

        return Crm.ContactTableDataSource.create({
            content: new Array(this.get('numRows')),
            store: this.get('store')
        });

    }).property('numRows'),

    actions: {

    }
});

Crm.ContactCheckboxTableCell = Ember.Table.TableCell.extend({
    templateName: 'contact-checkbox-cell',
    classNames: 'contact-checkbox-cell'
});

JSON response:

{
    "contacts": [
        {
            "id": 46,
            "prefix": null,
            "firstName": "Amy",
            "middleName": null,
            "lastName": "Wong",
            "suffix": null,
            "gender": null
        },
        {
            "id": 23,
            "prefix": null,
            "firstName": "Bender",
            "middleName": "Bending",
            "lastName": "Rodriguez",
            "suffix": null,
            "gender": null
        },
        {
            "id": 21,
            "prefix": null,
            "firstName": "Bro",
            "middleName": null,
            "lastName": "Namath",
            "suffix": null,
            "gender": null
        },
        {
            "id": 35,
            "prefix": null,
            "firstName": "Bruce",
            "middleName": null,
            "lastName": "Dickinson",
            "suffix": null,
            "gender": null
        },
        {
            "id": 39,
            "prefix": null,
            "firstName": "Chase",
            "middleName": null,
            "lastName": "Utley",
            "suffix": null,
            "gender": null
        },
        {
            "id": 25,
            "prefix": null,
            "firstName": "Clint",
            "middleName": null,
            "lastName": "Eastwood",
            "suffix": null,
            "gender": null
        },
        {
            "id": 14,
            "prefix": null,
            "firstName": "Digg",
            "middleName": null,
            "lastName": "Dugg",
            "suffix": null,
            "gender": null
        },
        {
            "id": 26,
            "prefix": null,
            "firstName": "Dirty",
            "middleName": null,
            "lastName": "Harry",
            "suffix": null,
            "gender": null
        },
        {
            "id": 32,
            "prefix": null,
            "firstName": "Doctor",
            "middleName": null,
            "lastName": "Dre",
            "suffix": null,
            "gender": null
        },
        {
            "id": 20,
            "prefix": null,
            "firstName": "Dude",
            "middleName": null,
            "lastName": "Von Manstein",
            "suffix": null,
            "gender": null
        },
        {
            "id": 30,
            "prefix": null,
            "firstName": "Eazy",
            "middleName": null,
            "lastName": "E",
            "suffix": null,
            "gender": null
        },
        {
            "id": 28,
            "prefix": null,
            "firstName": "Eli",
            "middleName": null,
            "lastName": "Roth",
            "suffix": null,
            "gender": null
        },
        {
            "id": 37,
            "prefix": null,
            "firstName": "Eric",
            "middleName": null,
            "lastName": "Clapton",
            "suffix": null,
            "gender": null
        },
        {
            "id": 22,
            "prefix": null,
            "firstName": "Hedonism",
            "middleName": null,
            "lastName": "Bot",
            "suffix": null,
            "gender": null
        },
        {
            "id": 43,
            "prefix": null,
            "firstName": "Hermes",
            "middleName": null,
            "lastName": "Conrad",
            "suffix": null,
            "gender": null
        },
        {
            "id": 15,
            "prefix": null,
            "firstName": "Homer",
            "middleName": null,
            "lastName": "Thompson",
            "suffix": null,
            "gender": null
        },
        {
            "id": 13,
            "prefix": null,
            "firstName": "Homey",
            "middleName": "The",
            "lastName": "Clown",
            "suffix": null,
            "gender": null
        },
        {
            "id": 45,
            "prefix": null,
            "firstName": "Hubert",
            "middleName": null,
            "lastName": "Farnsworth",
            "suffix": null,
            "gender": null
        },
        {
            "id": 31,
            "prefix": null,
            "firstName": "Ice",
            "middleName": null,
            "lastName": "Cube",
            "suffix": null,
            "gender": null
        },
        {
            "id": 38,
            "prefix": null,
            "firstName": "Jimi",
            "middleName": null,
            "lastName": "Hendrix",
            "suffix": null,
            "gender": null
        },
        {
            "id": 12,
            "prefix": null,
            "firstName": "John",
            "middleName": null,
            "lastName": "Jones",
            "suffix": null,
            "gender": null
        },
        {
            "id": 44,
            "prefix": null,
            "firstName": "John",
            "middleName": null,
            "lastName": "Zoidberg",
            "suffix": null,
            "gender": null
        },
        {
            "id": 27,
            "prefix": null,
            "firstName": "Lee",
            "middleName": null,
            "lastName": "Van Cleef",
            "suffix": null,
            "gender": null
        },
        {
            "id": 34,
            "prefix": null,
            "firstName": "Luther",
            "middleName": null,
            "lastName": "Vandross",
            "suffix": null,
            "gender": null
        },
        {
            "id": 11,
            "prefix": null,
            "firstName": "Markus",
            "middleName": null,
            "lastName": "Summerstein",
            "suffix": null,
            "gender": null
        },
        {
            "id": 29,
            "prefix": null,
            "firstName": "Marty",
            "middleName": null,
            "lastName": "McFly",
            "suffix": null,
            "gender": null
        },
        {
            "id": 24,
            "prefix": null,
            "firstName": "Phillip",
            "middleName": "J",
            "lastName": "Fry",
            "suffix": null,
            "gender": null
        },
        {
            "id": 40,
            "prefix": null,
            "firstName": "Phillip",
            "middleName": null,
            "lastName": "Fry",
            "suffix": null,
            "gender": null
        },
        {
            "id": 33,
            "prefix": null,
            "firstName": "Ping Pong",
            "middleName": null,
            "lastName": "Von Laserstein",
            "suffix": null,
            "gender": null
        },
        {
            "id": 41,
            "prefix": null,
            "firstName": "Robot",
            "middleName": null,
            "lastName": "Devil",
            "suffix": null,
            "gender": null
        }
    ]
}

And the template:

<div class="table-container" style="height:450px;">
    {{table-component
        hasFooter=false
        columnsBinding="columns"
        contentBinding="content"
        numFixedColumns=1
    }}
</div>

Edit: It looks as if it might be an Ember Data issue where my JSON response does not correctly deserialize to the model. When I type the following into the console:

Crm.Contact.find();
Crm.Group.find(); // another model of mine

For groups, I can see the array of records and their data values. For contact, I see the array of records but all the data is null. Any thoughts or hints would be greatly appreciated. I'm using: Ember 1.5.1, Ember Data 0.0.14, Handlebars 1.3.0, Ember Table 0.0.2 and jQuery 2.1.0.

Here's what I did to resolve:

  • Upgraded to Ember-Data 1.0.0-beta.7
  • Went through my code and made changes according to the migration guide here
  • Made a minor code change of "this.get('store')" to "this.store" in Crm.ContactsController content() method

A very straightforward way to bind the content of an ember-table is from within the template.

For your ember data, if you can view it through a template with the following code:

{{#each model as |part|}}
  <li>{{part.name}}</li>
{{/each}}

Then you should be able to bind the ember-table's content field similarly:

{{ember-table
 hasFooter=false
 columns=tableColumns
 content=model
}}

Where the model in both is identical, and properly loaded.

This seems much more straightforward then trying to calculate the content from within a controller itself, especially when using Ember-Data.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM