2013-09-25 61 views
2

我製成的圖表組件一旦觀察者火災,我希望它呈現每當出現以下情況之一:確保每次運行循環

  1. 它被插入到DOM
  2. 它的 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') 
}); 

我沒有時間做一個jsfidd現在,但所有情況都符合預期,但只有一種情況:我從index路線開始,然後加載模型,然後返回到index路線。在這一點上,數據爲以前的路線加載(比如公司A,B和C),但因爲我在index路線上,所以組件不會被渲染。現在,如果我點擊一個路線(說公司d,E,F),這裏會發生什麼(據我所知):

  • 沒有任何反應,直到承諾解決和新公司已加載
  • 加載完成後,companies模板被渲染。這會在我的組件中觸發didInsertElement,並運行update函數。
  • dataCompaniesController中的data計算的屬性會再次計算,並觸發其更改事件。
  • 我的組件中的update方法觀察data中的更改並重新顯示。

因此,圖表被渲染兩次,一次使用舊數據,一次使用新數據。如果它是瞬時的,也許它並不重要,但因爲它具有流暢的動畫效果,所以它是顯而易見的。

我認爲使用Ember.run.once可以防止這種情況發生,但我猜不是 - 或者我錯誤地使用了它。看起來我需要的不僅是檢查模型是否已加載,而且控制器是否已完成交換內容。我會非常感激任何想法!

+1

的'Ember.run.once'是像'Ember.run.scheduleOnce(「操作」是相同的, ...)',因爲在渲染視圖時需要執行update方法,因爲d3會更改渲染的dom。也許安全的方法是使用'Ember.run.scheduleOnce('afterRender',this,'update')'。 –

回答

0

我結束了手動清除上在進入索引路由控制器content屬性:

App.IndexRoute = Ember.Route.extend({ 
    setupController: function(controller, model) { 
    this.controllerFor('monthlyReport').set('content', null); 
    this.controllerFor('companies').set('content', null); 
    } 
});