How to include a component from a controller in em

2019-08-14 22:09发布

I'm working on an application in ember and have created a dynamic table component that will take a config object and a list of models then print a row out for each model with the columns specified in the config object.

I would like to extend the component to allow inline editing of the models. My thought would be that you could define what components and params in the config object that tie to each field.

The only way I can think to implement this is to create another component that is basically a switch statement of components building out the one that matches the case.

I'm curious if anyone has a better way to do this?

What I have So Far:

Config Obj (defined in controller):

modelsConfig: {
    getController: function() { return this; },
    modelType: 'event',
    add: {
        title: 'Add New',
        path: 'events.event',
        getParams: function(controller) { return {}; }
    },
    editPath: 'events.event',
    deleteIcon: true,
    tableFilter: {
        field: 'status',
        title: 'Filter Events:',
        options: [{
                icon: null,
                name: 'All',
                value: null
            }, {
                icon: 'circle-o',
                name: 'New',
                value: 'new'
            }, {
                icon: 'dot-circle-o',
                name: 'Closed',
                value: 'closed'
            }, {
                icon: 'circle',
                name: 'In Review',
                value: 'review'
            }, {
                icon: 'times-circle',
                name: 'Assigend Edits',
                value: 'assigned'
            }, {
                icon: 'check-circle',
                name: 'Complete',
                value: 'complete'
            }
        ]
    },
    search: { //Not sure we actually need this...
        searchedFields: ['orsIncidentIDNumber', 'irsIncidentIDNumber'],
        text: null //Default text
    },
    table: {
        statusIcon: 'status',//field of model to calculate the icon off of
        cols: [{
            header: 'ORS Indident ID #',
            field: 'orsIncidentIDNumber',
            component: {
                type: 'text',
                value: 'orsIncidentIDNumber',
            }
        },{
            header: 'IRS Indident ID #',
            field: 'irsIncidentIDNumber',
            component: {
                type: 'text',
                value: 'irsIncidentIDNumber',
            }
        },{
            header: 'Date/Time',
            field: 'date',,
            component: {
                type: 'date',
                value: 'date',
            }
        },{
            header: 'Address',
            field: 'address',
            component: {
                type: 'textarea',
                value: 'address',
            }
        },{
            header: 'Type',
            field: 'type',
            component: {
                type: 'select',
                store: typeStore,
                value: 'address',
            }
        }]
    },
    pagination: {
        start: 0,
        end: 0,
        perPage: 5
    }
}

Table template:

<div class="table-actions clearfix">
    {{#if config.tableFilter}}
        {{table-filters config=config.tableFilter filter="filterModels"}}
    {{/if}}
    {{#if config.search}}
        {{search-bar controllerSearchText=config.search.text search="searchModels"}}
    {{/if}}
</div>
<!-- Models table -->
<table>
    <thead>
        <tr>
            {{#if config.table.statusIcon}}
                <th>Status</th>
            {{/if}}
            {{#each col in config.table.cols}}
                <th>{{col.header}}</th>
            {{/each}}
            {{#if config.editPath}}
                <th>&nbsp;</th>
            {{/if}}
            {{#if config.deleteIcon}}
                <th>&nbsp;</th>
            {{/if}}
        </tr>
    </thead>
    <tbody>
        {{#each record in modelRange}}
        <tr>
            {{#if config.table.statusIcon}}
                <td>
                    {{{status-icon record config.table.statusIcon}}}
                </td>
            {{/if}}
            {{#each col in config.table.cols}}
            <td>
                {{#if col.component}}
                     <!-- include given component -->
                {{else}}
                     {{array-value record col.field }}<!-- Just returns record[col.field} -->
                {{/if}}
            </td>
            {{/each}}
            {{#if config.editPath}}
                {{#link-to config.editPath record.id tag="td" class="icon"}}
                    {{fa-icon 'pencil-square-o'}}
                {{/link-to}}
            {{/if}}
            {{#if config.deleteIcon}}
                <td class="icon">
                    <a href="#" {{action "deleteRecord" record}}>
                        {{fa-icon 'trash-o'}}
                    </a>
                </td>
            {{/if}}
        </tr>
        {{/each}}
    </tbody>
</table>
<!-- Models actions -->
<div class="table-actions">
    {{#if config.add.title}}
        <button {{action "addNew"}}>{{config.add.title}}</button>
    {{/if}}
    {{#if config.pagination}}
        {{pagination-component config=config.pagination actionController=this}}
    {{/if}}
</div>

Implementation:

{{table-list config=modelsConfig data=model}}

1条回答
时光不老,我们不散
2楼-- · 2019-08-14 22:57

Ember recently added support for dynamic components. For a model/object like:

[{
   cname: 'table',
   content: {
     statusIcon: 'status'
   }
 },
 {
   cname: 'search',
   content: {
     text: 'foobar'
   }
 }]

You can do this in a template:

{{#each item in object}}
   {{component item.cname content=item.content}}
{{/each}}

So you don't have to care about what you send to the template anymore. All you need to do is make sure that every item in the list complies to the cname and content convention.

查看更多
登录 后发表回答