在EmberJS中创建完全动态的表格

时间:2018-11-12 08:08:42

标签: javascript ember.js

我在EmberJS中定义了一个model,具有以下属性:

import DS from 'ember-data';

export default DS.Model.extend({
    "name": DS.attr('string'),
    "status": DS.attr('string'),
    "email1": DS.attr('string'),
    "account_name": DS.attr('string'),
    "phone_work": DS.attr('string'),
    "date_entered": DS.attr('string'),
    "date_modified": DS.attr('string')
});

我正在创建一个名为component的{​​{1}},它将把这些属性呈现到一个表中(标题,正文;就像列出某些字段的典型表一样)。但是,我不想使表仅绑定到此fields-list,而是希望使model完全动态,以便具有不同字段名称的其他模型也可以重用此component来生成它们表也​​是如此。

这样,每当使用component时,它都会检测到component并根据该model中的字段填充表头和正文。

我该如何实现?如果查询中有任何不清楚的地方,请告诉我,我已尽我所能尽可能地正确解释了该问题。预先感谢!

2 个答案:

答案 0 :(得分:1)

我个人不使用Ember Data,因此可能会有更好的方法来做您正在做的事情,但是我为您提供了ember twiddlegist的解决方案。这无非是概念的证明。

让我们快速地分解问题。您想要创建一个可以采用任何模型并神奇地为您构建表的组件。在最高级别,我们知道我们需要能够遍历数据模型的定义,并根据您以DS.attr传递的Ember Data类型创建特定类型的列。进一步考虑,我们知道Ember Data必须具有某种能力来做到这一点:eachAttribute。如果它是私有API,则应识别这是易碎的和特定于版本的(也称为写测试)。

因此,给定模型Foo:

import Model from 'ember-data/model';
import attr from 'ember-data/attr';

export default Model.extend({
    "name": attr('string'),
    "status": attr('string')
});

让我们通过构造函数获取模型的定义:

var record = this.store.createRecord('foo', {
    name: "model1",
    status: "status1"
});
this.modelClass = record.constructor;

Ember light表采用一个列定义对象,我们可以通过在所述模型类上使用eachAttribute从组件内部动态创建该列定义对象:

columns: computed('modelClass', function() {
    let modelClass = this.modelClass;
    if(!modelClass){ return [] }
    let columns = [];
    modelClass.eachAttribute(function(key, meta){ 
      columns.push({
         label: key,
         valuePath: key
      });
    });
    return columns;
})

在这里,您可以检查meta函数的eachAttribute参数中每种属性的特定类型,以在列定义中设置cellComponent属性,如果您要呈现不同的属性单元格类型。

有一个名为Ember Admin的项目会自动从您的数据模型中构建一个CRUD接口,因此可以找到灵感。

答案 1 :(得分:1)

如果您可以自己构建插件,为什么要使用插件?

app/templates/some-route.hbs

<FieldsList
  @resources={{users}}
  @columns='id, firstName, lastName, job.title, job.company.name'
  @sortBy='firstNameAsc'
  @filterBy='firstName, lastName'
/>

app/components/fields-list/component.js

import Component from '@ember/component';
import { computed } from '@ember/object';

export default Component.extend({
  classNames: ['fields-list'],

  // Splits the string of keys into an array
  columnMap: computed(function() {
    return this.columns.replace(/ /g, '').split(/,/g);
  })
});

app/components/fields-list/template.hbs

<ul>
  {{#each resources as |resource|}}
    <li>
      {{#each columnMap as |column|}}
        <span>{{get resource key}}</span>
      {{/each}}
    </li>
  {{else}}
    <li>No humans found</li>
  {{/each}}
</ul>

app/components/fields-list/style.scss

.fields-list {
  li {
    display: flex;
    span {
      flex: 1;
    }
  }
}

在ember-cli中完成:3.5.0