在 EmberJS 中创建完全动态的 table
Create a fully dynamic table in EmberJS
我在 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')
});
我正在创建一个名为 fields-list
的 component
,它会将这些属性呈现为 table(headers、body;就像典型的 table 列出一些字段)。但是,我不想让 table 只绑定到这个 model
,我想让 component
完全动态,这样其他具有不同字段名称的模型也可以重用这个 component
来生成它们的 tables。
这样,无论何时使用 component
,它都会检测 model
并填充 table 的 headers 以及 body根据 model
.
中的字段
我该如何实现?如果查询中有任何不清楚的地方,请告诉我,我已尽力尽可能正确地解释问题。提前致谢!
我个人不使用 Ember 数据,因此可能有更好的方法来完成您正在做的事情,但我为您提供了一个解决方案 ember twiddle or as a gist。这只不过是一个概念证明。
让我们快速分解问题。您想要创建一个可以采用任何模型并神奇地为您构建 table 的组件。在最高级别,我们知道我们需要能够迭代数据模型的定义并根据您作为 DS.attr
传递的 Ember 数据类型创建特定类型的列。进一步思考,我们知道 Ember 数据必须具有某种能力来做同样的事情: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 table 采用列定义对象,我们可以通过在所述模型 class 上使用 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;
})
您可以在此处检查 eachAttribute
函数的 meta
参数以了解每个属性的特定类型,以在列定义中设置 cellComponent
属性你应该渲染不同的细胞类型吗?
有一个名为 Ember Admin 的项目可以根据您的数据模型自动构建一个 CRUD 界面,因此有一个灵感来源。
如果可以自己构建,为什么还要求助于插件?
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
中完成
我在 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')
});
我正在创建一个名为 fields-list
的 component
,它会将这些属性呈现为 table(headers、body;就像典型的 table 列出一些字段)。但是,我不想让 table 只绑定到这个 model
,我想让 component
完全动态,这样其他具有不同字段名称的模型也可以重用这个 component
来生成它们的 tables。
这样,无论何时使用 component
,它都会检测 model
并填充 table 的 headers 以及 body根据 model
.
我该如何实现?如果查询中有任何不清楚的地方,请告诉我,我已尽力尽可能正确地解释问题。提前致谢!
我个人不使用 Ember 数据,因此可能有更好的方法来完成您正在做的事情,但我为您提供了一个解决方案 ember twiddle or as a gist。这只不过是一个概念证明。
让我们快速分解问题。您想要创建一个可以采用任何模型并神奇地为您构建 table 的组件。在最高级别,我们知道我们需要能够迭代数据模型的定义并根据您作为 DS.attr
传递的 Ember 数据类型创建特定类型的列。进一步思考,我们知道 Ember 数据必须具有某种能力来做同样的事情: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 table 采用列定义对象,我们可以通过在所述模型 class 上使用 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;
})
您可以在此处检查 eachAttribute
函数的 meta
参数以了解每个属性的特定类型,以在列定义中设置 cellComponent
属性你应该渲染不同的细胞类型吗?
有一个名为 Ember Admin 的项目可以根据您的数据模型自动构建一个 CRUD 界面,因此有一个灵感来源。
如果可以自己构建,为什么还要求助于插件?
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
中完成