Данные диаграммы объекта перезаписываются, но затрагивается только первый объект, с которым взаимодействовали

Вот эта песочница кода, доказывающая и демонстрирующая эту проблему: https://codesandbox.io/embed/ql4rm9734w?fontsize=14

Когда пользователь нажимает кнопку в файле app. Виджет предназначен для отображения данных этого объекта. Объект содержит массив, который используется для создания графика. Нажатие кнопки первого объекта отображается и работает правильно. Так же и второе и третье. Но когда кнопка первого объекта снова нажимается, свойство данных диаграммы объекта перезаписывается данными диаграммы объекта, который был нажат ранее.

Приложение было построено на Vue.Js, с Highcharts и официальной оболочкой Highcharts Vue для рендеринга диаграмм. Данные хранятся в хранилище Vuex.

Страница заполняется кнопкой для каждого объекта. При нажатии кнопки объектов запускается пользовательское событие, содержащее данные объекта. Обработчик события щелчка объекта изменяет хранилище, передавая объект в хранилище для сохранения в качестве активного объекта-маркера. Объект Widget, отображающий данные для пользователя, получает свои данные из хранилища активного объекта-маркера.

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

Я пробовал следующее без везения

  • Инструменты разработки и отладки Vue показывают симптомы ошибки, но не указывают, где она возникает.
  • Я попытался сделать свойство данных псевдоприватным, к которому можно получить доступ только с помощью сеттеров и геттеров. Сеттер никогда не вызывается.
  • Добавлено второе свойство в классе, чтобы действовать как неизменяемая переменная хранения для исходных данных, заданных во время построения. Это второе свойство также изменяется.
  • При детальном изучении магазина оказалось, что массив объектов в магазине не был затронут ошибкой. Однако при рефакторинге для прямого использования объекта из хранилища ошибка все еще существует.
  • Я попытался выделить данные в отдельное свойство состояния, которое не имеет прямого отношения к объекту... все та же ошибка.
  • Я также пробовал с каждым небольшим массивом данных (15 элементов), но ошибка сохранялась.
  • Я даже создал проект мини-реплики в надежде, что в самом маленьком масштабе ошибка не появится, и надеюсь, что это будет глупая опечатка или что-то в этом роде... но опять же, даже эта мини-версия моего приложения все еще показывает ошибку. Мини-версию можно найти здесь: https://github.com/ChadRoberts21/ChartMapBug
  • Построен более совершенный пример меньшего размера: https://codesandbox.io/embed/ql4rm9734w?fontsize=14

Код доступен от https://codesandbox.io/embed/ql4rm9734w?fontsize=14

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

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
127
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я думаю, проблема в том, что вы используете вычисление для выборки данных. когда вы передаете данные в событии клика, он фактически обновляет массив foos хранилища (ссылка на state.foos). поэтому, когда вы нажимаете на test2, данные в хранилище массива foos обновляются.

Попробуйте консолидировать массив log foos в методе store setActiveFoo, и вы увидите, что массив foos обновляется другими значениями.

setActiveFoo(state, payload) {
      console.info("In store foos")
      console.info(state.foos);
      state.activeFoo = payload;
    }

Попробуйте этот код. Я думаю, вам нужно отправить копию массива foos в вычислении, это решит проблему.

computed: {
    foos() {
      return JSON.parse(JSON.stringify(this.$store.getters.foos));
    },
    activeFoo() {
      return JSON.parse(JSON.stringify(this.$store.getters.activeFoo));
    }
  }

Это не должно работать, но работает. Я по-прежнему считаю, что существует гораздо более глубокая проблема. Почему другие свойства объекта не затрагиваются той же проблемой? В моем производственном приложении у меня есть огромный сложный вложенный объект, который отлично работает, за исключением единственного свойства, которое использует highcharts. Спасибо за ваш ответ, я очень ценю это!

Chad Roberts 12.04.2019 09:56

другие свойства объекта не влияют на bcz, вы не используете его при отправке, а также в других методах. вы просто используете массив состояния foo, поэтому он влияет только на массив foos. и попробуйте изменить значение, тогда оно также обновит переменную состояния.

Patel Pratik 12.04.2019 11:31
Ответ принят как подходящий

Проблема возникает из-за того, что Highcharts мутирует данные, что не совсем соответствует представлениям Vue. Как правило, если вы можете избежать мутации данных, вам вообще не следует этого делать. Я только что ответил на этот вопрос прямо в репозитории highcharts-vue, так что там вы можете найти более подробное описание того, почему возникает проблема.

По сути (для других пользователей, которые ищут ответ на этот вопрос), лучшим выходом из проблемы будет применение спред оператор при назначении новых данных серии:

FooWidget.vue (часть вычисляемого свойства Опции диаграммы())

series: [{
    showInLegend: false,
    type: "column",
    color: this.foo.colour,
    data: [...this.foo.data],
    pointInterval: this.foo.interval,
    pointStart: this.foo.startPoint,
    gapSize: 4,
    tooltip: {
        valueDecimals: 2
    },
    fillColor: {
        linearGradient: {
            x1: 0,
            y1: 0,
            x2: 0,
            y2: 1
        }
     },
     threshold: null
 }]

Живой пример: https://codesandbox.io/s/w2wyx88vxl

С наилучшими пожеланиями!

Другие вопросы по теме