AmCharts 3 - Удалить слушателя при первом запуске (функция ссылки внутри себя) - PullRequest
4 голосов
/ 01 апреля 2019

Я хотел бы знать, как добавить слушателя, который запускается только один раз, я думаю, в конце концов, это в основном общий вопрос javascript, но я могу что-то упустить.

Вот что у меня есть:

const listener = chart.addListener('rendered', () => {
    console.log('Chart rendered! This should only print once!');
    doSomethingToChart(chart);
    chart.removeListener(chart, 'rendered', listener);
})

Проблема в том, что не удаляется прослушиватель, а console.log печатает при каждом рендере. Как я могу это исправить?

Ответы [ 2 ]

2 голосов
/ 02 апреля 2019

addListener вообще не имеет возвращаемого значения и не упоминает об одном в документации , поэтому ваш код не работает.Просто сохраните ссылку на функцию отдельно перед добавлением списка, затем вызовите removeListener для этой ссылки, и она будет работать, например:

let counter = 0;
const listener = () => {
  console.log('dataUpdated called', counter += 1);
};

chart.addListener('dataUpdated', listener);

let timer = setInterval(() => {
  chart.validateData(); //triggers dataUpdated
  if (counter == 3)  {
    chart.removeListener(chart, 'dataUpdated', listener);
    console.log('dataUpdated removed')
    chart.validateData(); //one more call to confirm that the listner no longer runs
    clearInterval(timer);
  }

}, 1500);

Демо:

var chart = AmCharts.makeChart("chartdiv", {
  "type": "serial",
  "theme": "light",
  "dataProvider": [{
    "country": "USA",
    "visits": 2025
  }, {
    "country": "China",
    "visits": 1882
  }, {
    "country": "Japan",
    "visits": 1809
  }, {
    "country": "Germany",
    "visits": 1322
  }, {
    "country": "UK",
    "visits": 1122
  }, {
    "country": "France",
    "visits": 1114
  }, {
    "country": "India",
    "visits": 984
  }, {
    "country": "Spain",
    "visits": 711
  }, {
    "country": "Netherlands",
    "visits": 665
  }, {
    "country": "Russia",
    "visits": 580
  }, {
    "country": "South Korea",
    "visits": 443
  }, {
    "country": "Canada",
    "visits": 441
  }, {
    "country": "Brazil",
    "visits": 395
  }],
  "graphs": [{
    "fillAlphas": 0.9,
    "lineAlpha": 0.2,
    "type": "column",
    "valueField": "visits"
  }],
  "categoryField": "country"
}, 100);

let counter = 0;
const listener = () => {
  console.log('dataUpdated called', counter += 1);
};

chart.addListener('dataUpdated', listener);

let timer = setInterval(() => {
  chart.validateData(); //this triggers dataUpdated
  if (counter == 3) {
    chart.removeListener(chart, 'dataUpdated', listener);
    console.log('dataUpdated removed')
    chart.validateData(); //confirm that listner isn't called anymore
    clearInterval(timer);
  }

}, 1500);
html,
body {
  width: 100%;
  height: 100%;
  margin: 0px;
}

#chartdiv {
  width: 100%;
  height: 100%;
}
<script src="//www.amcharts.com/lib/3/amcharts.js"></script>
<script src="//www.amcharts.com/lib/3/serial.js"></script>
<script src="//www.amcharts.com/lib/3/themes/light.js"></script>

<div id="chartdiv"></div>
0 голосов
/ 01 апреля 2019

Просто используйте, используйте слушателя так:

const listener = () => {
    console.log('Chart rendered! This should only print once!');
    // ...
    chart.removeListener(chart, 'rendered', listener);
};

chart.addListener('rendered', listener);

Здесь - кодовая ручка, показывающая поведение.


В качестве альтернативы вы можете использовать внешнюю переменную для сохранения состояния:

let executedOnce = false;
chart.addListener('rendered', () => {
    if (executedOnce) {
      return;
    }
    executedOnce = true;
    console.log('Chart rendered! This should only print once!');
    // ...
});

Кроме того, я бы порекомендовал перейти на , потому что он намного более гибок и имеет даже новые типы диаграмм. Вы можете легко мигрировать, начиная с одного графика. Вы можете использовать amcharts3 и amcharts4 параллельно ( Руководство по миграции ).

В amcharts4 вы можете один раз подписаться на событие ( docs ):

chart.events.once('datavalidated' => {
    // ...
});
...