我制作了一个图表组件,我想让它在下列任何一种情况下呈现:
data
属性更改问题是,如果这两个事件都发生,图表会被渲染两次。
这是组件:
App.BarChartComponent = Ember.Component.extend({
classNames: ['chart'],
chart: BarChart().margin({left: 40, top: 40, bottom: 80, right: 40}),
didInsertElement: function() {
Ember.run.once(this, 'update');
},
update: function() {
if (this.get('isLoaded')) {
d3.select(this.$()[0])
.data([ this.get('data') ])
.call(this.get('chart'));
}
}.observes('data')
});
我正在使用它(它在公司模板中呈现)
{{bar-chart data=controller.controllers.companies.data
isLoaded=controller.controllers.companies.model.isLoaded}}
控制器看起来像这样(更改路径更新CompaniesController
模型):
App.CompaniesController = Ember.ArrayController.extend({
data: function() {
if (!this.get('model.isLoaded')) {return;}
var data = this.map(function(company) {
return {
category: company.get('name'),
count: company.get('newContracts'),
};
});
return data;
}.property('model')
});
我现在没有时间制作一个jsfiddle,但除了一种情况外,一切都按预期工作:我从index
路线开始,然后加载模型,然后返回到index
路线。此时,数据将加载前一个路由(比如公司A,B和C),但因为我在index
路由上,所以组件未被渲染。现在,如果我点击新路线(比如公司D,E,F),这就是发生的事情(据我所知):
companies
模板即会呈现。这会在我的组件中触发didInsertElement
,并运行update
函数。data
中的CompaniesController
计算属性再次计算,触发其更改事件。update
方法会观察data
中的更改并重新呈现自己。因此,图表会呈现两次,一次是旧数据,一次是新数据。如果它是瞬间的,也许没关系,但因为它有一个平滑的动画,它是显而易见的。
我认为使用Ember.run.once
可以防止这种情况发生,但我猜不会 - 或者我使用它不正确。看起来我需要的是不仅要检查模型是否已加载,还要检查控制器是否已完成交换其内容。我非常感谢任何想法!
答案 0 :(得分:0)
我最后在输入索引路径时手动清除控制器上的content
属性:
App.IndexRoute = Ember.Route.extend({
setupController: function(controller, model) {
this.controllerFor('monthlyReport').set('content', null);
this.controllerFor('companies').set('content', null);
}
});