я сделал компонент диаграммы, и я хочу, чтобы сделать каждый раз, когда один из следующих случаев:Обеспечение пожаров наблюдателей раза за цикл выполнения
- Его
data
свойства изменяет - Он вставляется в DOM
Проблема в том, что если оба этих события происходят, диаграмма получает визуализацию дважды.
Вот компонент:
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 le прямо сейчас, но все работает так, как ожидалось, во всех случаях, кроме одного: где я начинаю с маршрута index
, затем загружаю модель, а затем возвращаюсь к маршруту index
. На данный момент данные загружаются для предыдущего маршрута (например, компании A, B и C), но поскольку я нахожусь на маршруте index
, компонент не отображается. Теперь, если я нажму на новый маршрут (скажем, компании D, E, F), вот что происходит (насколько мне известно):
- Ничего не происходит, пока обещание не решит, а новые компании Загружено
- Как только они загружаются, создается
companies
. Это вызываетdidInsertElement
в моем компоненте и запускает функциюupdate
. - Вычисленное свойство
data
в моемCompaniesController
вычислено, активировав его событие изменения. - Метод
update
в моем компоненте наблюдает за изменениемdata
и редертирует себя.
Итак, график получает визуализированный дважды, один раз со старыми данными и один раз с новым. Если бы это было мгновенно, возможно, это не имело бы никакого значения, но потому, что оно имеет гладкую анимацию, это заметно.
Я думал, что использование Ember.run.once
предотвратит это, но я думаю, что нет - или я использую его неправильно. Похоже, мне нужно проверить не только загрузку модели, но и контроль над ее контентом. Я был бы очень признателен за любые идеи!
Параметр 'Ember.run.once' такой же, как' Ember.run.scheduleOnce («действия», ...) ', потому что вам нужен метод обновления, который будет выполняться при визуализации вашего представления, потому что d3 изменит ваш отображаемый dom. Возможно, безопасный способ сделать это - использовать 'Ember.run.scheduleOnce ('afterRender', это, 'update')'. –