EmberJS:如何从控制器调用组件函数并计算组件数据
EmberJS: How to call a component function from a controller and calculate the component data
我创建了一条路由,比如说日志(pods 结构),我创建了 controller.js、route.js 和 template.hbs
在模板中我初始化了一个网格组件。我也在开发自定义分页组件。
当我初始化网格组件时,我将数据作为属性,这些数据在从分页更改页面后会发生变化,我还想计算页面大小,网格容器中适合多少行。通过 pageSize 我可以计算出总页数。
我在网格组件中有计算 pageSize 的功能,但我想在我的 controller.js 中使用该数字。我通过发送操作来做到这一点,并且我已经成功地在我的控制器上输入了号码。
然后在 dataHandler computed 属性 我想计算网格将显示的数据。我收到了弃用错误,并且网格中也没有显示任何内容:
弃用:在 didInsertElement 挂钩中修改了 属性。你永远不应该在 didInsertElement 期间更改组件、服务或模型的属性,因为它会导致性能显着下降。 [弃用 ID:ember-views.dispatching-modify-属性]
这种情况可能吗?如果是,最好的方法是什么?
在我的代码下面:
logs/controller.js
export default Ember.Controller.extend({
dataHandler: Ember.computed('pageSize', {
set(key, value) {
if (value) {
this.set('pageSize', value);
} else {
this.set('pageSize', null);
}
return value;
},
get() {
let data = this.get('data');
if (!data) {
let pageSize = this.get('pageSize');
data = this._data(); //Here will calculate the data and pass them to component
this.set('data', data);
}
return data;
}
}),
actions: {
setPageSizeFromDataGrid(pageSize) {
this.set('dataHandler', pageSize);
}
}
});
logs/template.hbs
<div class='row'>
<div class='col-md-12'>
<h1>Request Logs</h1>
{{#si-data-grid data=dataHandler rowHeight=35 pageSize="setPageSizeFromDataGrid"}}
//some content
{{/si-data-grid}}
</div>
</div>
我的component.js
export default Ember.Component.extend({
didRender() {
let that = this;
that._calculateContainerHeight();
let children = that.childViews;
let rowHeight = that.rowHeight || 20;
let data = that.data;
let columns = that._parseColumns(children);
let pageSize = that.getPageSize(rowHeight);
that.sendAction('pageSize', pageSize);
Ember.$(that.get('element')).find('div#si-data-grid').kendoGrid({
columns: columns,
dataSource: new kendo.data.DataSource({
data: data
})
});
Ember.$(that.get('element')).find('div#si-data-grid tr').css('height', rowHeight);
},
getPageSize(rowHeight) {
let paginationHeight = 40;
let gridHeaderHeight = this.$().offsetParent().offset().top;
let height = this.$().height() - gridHeaderHeight - paginationHeight;
return Math.floor(height / rowHeight);
}
});
我设法找到了解决问题的方法。
在我的 component.js 中,我添加了 didInsertElement 并安排 afterRender 发送操作
export default Ember.Component.extend({
didInsertElement() {
Ember.run.scheduleOnce('afterRender', this, '_updateChildViews');
},
didRender() {
//some code
},
_updateChildViews() {
let that = this;
let rowHeight = that.rowHeight;
let pageSize = that._getPageSize(rowHeight);
this.sendAction('updateData', pageSize);
}
});
在 logs/template.hbs
<div class='row'>
<div class='col-md-12'>
<h1>Request Logs</h1>
{{#si-data-grid data=dataHandler rowHeight=35 updateData='updateData'}}
//some code
{{/si-data-grid}}
</div>
</div>
和我的 logs/controller.js
export default Ember.Controller.extend({
dataHandler: Ember.computed('pageSize', {
set(key, value) {
if (value) {
this.set('data', this._data()); //calculate the data to be shown on the data grid component
} else {
this.set('data', []);
}
return this.get('data');
},
get() {
let data = this.get('data');
if (!data) {
this.set('data', []);
}
return data;
}
}),
actions: {
updateData(pageSize) {
this.set('dataHandler', pageSize);
}
}
});
我创建了一条路由,比如说日志(pods 结构),我创建了 controller.js、route.js 和 template.hbs
在模板中我初始化了一个网格组件。我也在开发自定义分页组件。
当我初始化网格组件时,我将数据作为属性,这些数据在从分页更改页面后会发生变化,我还想计算页面大小,网格容器中适合多少行。通过 pageSize 我可以计算出总页数。
我在网格组件中有计算 pageSize 的功能,但我想在我的 controller.js 中使用该数字。我通过发送操作来做到这一点,并且我已经成功地在我的控制器上输入了号码。
然后在 dataHandler computed 属性 我想计算网格将显示的数据。我收到了弃用错误,并且网格中也没有显示任何内容:
弃用:在 didInsertElement 挂钩中修改了 属性。你永远不应该在 didInsertElement 期间更改组件、服务或模型的属性,因为它会导致性能显着下降。 [弃用 ID:ember-views.dispatching-modify-属性]
这种情况可能吗?如果是,最好的方法是什么?
在我的代码下面:
logs/controller.js
export default Ember.Controller.extend({
dataHandler: Ember.computed('pageSize', {
set(key, value) {
if (value) {
this.set('pageSize', value);
} else {
this.set('pageSize', null);
}
return value;
},
get() {
let data = this.get('data');
if (!data) {
let pageSize = this.get('pageSize');
data = this._data(); //Here will calculate the data and pass them to component
this.set('data', data);
}
return data;
}
}),
actions: {
setPageSizeFromDataGrid(pageSize) {
this.set('dataHandler', pageSize);
}
}
});
logs/template.hbs
<div class='row'>
<div class='col-md-12'>
<h1>Request Logs</h1>
{{#si-data-grid data=dataHandler rowHeight=35 pageSize="setPageSizeFromDataGrid"}}
//some content
{{/si-data-grid}}
</div>
</div>
我的component.js
export default Ember.Component.extend({
didRender() {
let that = this;
that._calculateContainerHeight();
let children = that.childViews;
let rowHeight = that.rowHeight || 20;
let data = that.data;
let columns = that._parseColumns(children);
let pageSize = that.getPageSize(rowHeight);
that.sendAction('pageSize', pageSize);
Ember.$(that.get('element')).find('div#si-data-grid').kendoGrid({
columns: columns,
dataSource: new kendo.data.DataSource({
data: data
})
});
Ember.$(that.get('element')).find('div#si-data-grid tr').css('height', rowHeight);
},
getPageSize(rowHeight) {
let paginationHeight = 40;
let gridHeaderHeight = this.$().offsetParent().offset().top;
let height = this.$().height() - gridHeaderHeight - paginationHeight;
return Math.floor(height / rowHeight);
}
});
我设法找到了解决问题的方法。
在我的 component.js 中,我添加了 didInsertElement 并安排 afterRender 发送操作
export default Ember.Component.extend({
didInsertElement() {
Ember.run.scheduleOnce('afterRender', this, '_updateChildViews');
},
didRender() {
//some code
},
_updateChildViews() {
let that = this;
let rowHeight = that.rowHeight;
let pageSize = that._getPageSize(rowHeight);
this.sendAction('updateData', pageSize);
}
});
在 logs/template.hbs
<div class='row'>
<div class='col-md-12'>
<h1>Request Logs</h1>
{{#si-data-grid data=dataHandler rowHeight=35 updateData='updateData'}}
//some code
{{/si-data-grid}}
</div>
</div>
和我的 logs/controller.js
export default Ember.Controller.extend({
dataHandler: Ember.computed('pageSize', {
set(key, value) {
if (value) {
this.set('data', this._data()); //calculate the data to be shown on the data grid component
} else {
this.set('data', []);
}
return this.get('data');
},
get() {
let data = this.get('data');
if (!data) {
this.set('data', []);
}
return data;
}
}),
actions: {
updateData(pageSize) {
this.set('dataHandler', pageSize);
}
}
});