angular-highcharts: событие щелчка не может загрузить функцию из «этой» области - PullRequest
0 голосов
/ 10 мая 2018

Я использую угловые старшие диаграммы (https://www.npmjs.com/package/angular-highcharts), Я могу обнаружить события, но не могу загрузить функцию.

Запись события предназначена для нажатия на любую из точек серии ...

events: {
    click: function(event) {
        alert("Highcharts event click detected... Next action will be to load 'myFunction'.. check the console for error");
        this.myFunction();
    }
}

Он должен загрузить «myFunction ()», которая является простым предупреждением.

myFunction() {
    alert("myFunction executed");
}

Вместо этого ошибка в журнале консоли:

> ERROR TypeError: this.myFunction is not a function

Это прекрасно работает в "ванильном" Javascript, но не в angular-highcharts.

угловой (нерабочий):

https://stackblitz.com/edit/angular-8v1obg

ваниль (рабочий):

http://jsfiddle.net/marty232/kkgygaya/3/

Как мне получить угловую версию для загрузки функции?

Обновление
Q: Почему я хочу иметь возможность загружать функцию?
A: Когда пользователь щелкает точку данных, мне нужно запускать различные внешние сервисы, изменять переменные, обновлять HTML и т. Д. Поэтому, хотя мой пример заключается в доступе к одной функции, мне нужно в основном иметь возможность чтобы получить доступ к «любой» функции или объекту в области «this» (и в идеале, в других областях). Надеюсь, что это имеет смысл.

1 Ответ

0 голосов
/ 10 мая 2018

Кажется, проблема в том, что вы теряете свою область при выполнении события click в вашем угловом примере. Ссылка на this в этот момент выполнения отличается от того, что вы ожидаете. В вашем ванильном примере вы ссылаетесь на функцию, которая находится в той же области видимости.

Одним из решений может быть не привязка вашей функции для выполнения к самому компоненту, а создание ее в виде локальной переменной внутри блока, в котором вы инициируете старшие диаграммы.

init() {
  // create the function in the same scope so it does not have to rely on "this"
  var myFunction=()=> {
     alert("myFunction is now properly executed");
  }

  let chart = new Chart({
    ..
    plotOptions: {
      series: {
        lineWidth: 2,
        events: {
          click: function(event) {
            alert("Highcharts event click detected... Next action will be to load 'myFunction'.. check the console for error");
            myFunction();          }
        }
      },
    },
    ...
  });
  ...
}

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

EDIT

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

То, что мы можем сделать, чтобы сохранить функцию привязанной к компоненту, чтобы вы могли по-прежнему вызывать ее, например, из HTML, но также иметь возможность использовать ее внутри события щелчка диаграммы, - это предоставить ее вашему init() функция в качестве параметра. Чем больше я думаю об этом, тем больше я думаю, что это чертовски грязно. Вот как это выглядит тогда.

myFunction() {alert("myFunction executed");}

ngOnInit() {
  // transport the function
  this.init(this.myFunction);
}

init(myFunction) {
  // now it is untied from the "this" scope
  let chart = new Chart({
    chart: {
      type: 'line'
    },
    plotOptions: {
      series: {
        lineWidth: 2,
        events: {
          click: function(event) {
            alert("Highcharts event click detected... Next action will be to load 'myFunction'.. check the console for error");
            // use the variable instead of the private function
            myFunction();          }
        }
      },

    },
    ...
  });
  ...
}

В конечном счете, при вызове из диаграммы вы не сможете делать вещи внутри своей функции , которые относятся к контексту компонентов, например, изменять переменные или пытаться получить доступ к частным сервисам. Так что, в конце концов, это зависит от того, что вы хотите с ним сделать.

РЕДАКТИРОВАТЬ 2

Может быть, это немного чище. Вместо того, чтобы предоставлять функцию без области, мы связываем всю область в переменную. Обычно это делается путем установки переменной типа var that=this.

init() {
  // let's save the whole scope in a variable, so it is know to the functions scope
  let componentScope = this;

  let chart = new Chart({
    chart: {
      type: 'line'
    },
    plotOptions: {
      series: {
        lineWidth: 2,
        events: {
          click: function(event) {
            alert("Highcharts event click detected... Next action will be to load 'myFunction'.. check the console for error");
            // use the component scope here
            componentScope.myFunction();          }
        }
      },

    },
    ...
  });
  ...
}

Я думаю, что это должно сработать. Я думаю, что сохранение всей области означает, что вы также можете получить доступ ко всему остальному в ней, например, к функциям закрытых компонентов, переменным, службам и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...