Не удается суммировать вычисления с AlpineJS

Я делаю систему, чтобы купить рекламу для рекламы, поэтому каждая реклама может иметь звезды и дни. Мне нужно подсчитать сумму баллов для каждого объявления, а затем суммировать все баллы, необходимые для всех объявлений. Проблема в том, что Total всегда равен нулю, и я не получаю никаких ошибок. Почему?

<div x-data = "{ total: 0 }">
  <div class = "flex" x-data = "{ days: 1, stars: 1 }">
    <select x-model = "days" @change = "updateTotal()">
      <option value = "1">1 day</option>
      <option value = "2">2 days</option>
      <option value = "3">3 days</option>
    </select>

    <select x-model = "stars" @change = "updateTotal()">
      <option value = "1">1 star</option>
      <option value = "2">2 stars</option>
      <option value = "3">3 stars</option>
    </select>

    <div x-text = "days * stars" id = "sum"></div>
  </div>

  <div class = "flex" x-data = "{ days: 1, stars: 1 }">
    <select x-model = "days" @change = "updateTotal()">
      <option value = "1">1 day</option>
      <option value = "2">2 days</option>
      <option value = "3">3 days</option>
    </select>

    <select x-model = "stars" @change = "updateTotal()">
      <option value = "1">1 star</option>
      <option value = "2">2 stars</option>
      <option value = "3">3 stars</option>
    </select>

    <div x-text = "days * stars" id = "sum"></div>
  </div>

  <div class = "flex" x-data = "{ days: 1, stars: 1 }">
    <select x-model = "days" @change = "updateTotal()">
      <option value = "1">1 day</option>
      <option value = "2">2 days</option>
      <option value = "3">3 days</option>
    </select>

    <select x-model = "stars" @change = "updateTotal()">
      <option value = "1">1 star</option>
      <option value = "2">2 stars</option>
      <option value = "3">3 stars</option>
    </select>

    <div x-text = "days * stars" id = "sum"></div>
  </div>

  <div x-text = "'Total: ' + total"></div>

  <script src = "https://cdn.jsdelivr.net/npm/alpinejs@3"></script>
  <script src = "https://code.jquery.com/jquery-3.6.0.min.js"></script>
  <script>
    $(document).ready(function() {
      updateTotal();
    });

    function updateTotal() {
      var total = 0;
      $('#sum').each(function() {
        var value = parseInt($(this).text());
        if (!isNaN(value)) {
          total += value;
        }
      });
      Alpine.store('total', total);
    }

    Alpine.data('example', () => ({
      total: Alpine.store('total'),

      mounted() {
        this.$watch('$refs.sum', () => {
          updateTotal();
          this.total = Alpine.store('total');
        });
      },
    }));
  </script>
</div>
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
0
82
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я не уверен на 100%, но, во-первых, у вас есть несколько id="sum", где они должны быть уникальными. Он получает только первый элемент. Вместо этого вы можете использовать класс.

<div x-text = "days * stars" class = "sum"></div>

Так что это дало бы

$('.sum').each(function() {
    var value = parseInt($(this).text());
    if (!isNaN(value)) {
      total += value;
    }
});
Alpine.store('total', total);

Все вместе:

<div x-data = "{ total: 0 }">
  <div class = "flex" x-data = "{ days: 1, stars: 1 }">
    <select x-model = "days" @change = "updateTotal()">
      <option value = "1">1 day</option>
      <option value = "2">2 days</option>
      <option value = "3">3 days</option>
    </select>

    <select x-model = "stars" @change = "updateTotal()">
      <option value = "1">1 star</option>
      <option value = "2">2 stars</option>
      <option value = "3">3 stars</option>
    </select>

    <div class = "sum" x-text = "days * stars"></div>
  </div>

  <div class = "flex" x-data = "{ days: 1, stars: 1 }">
    <select x-model = "days" @change = "updateTotal()">
      <option value = "1">1 day</option>
      <option value = "2">2 days</option>
      <option value = "3">3 days</option>
    </select>

    <select x-model = "stars" @change = "updateTotal()">
      <option value = "1">1 star</option>
      <option value = "2">2 stars</option>
      <option value = "3">3 stars</option>
    </select>

    <div class = "sum" x-text = "days * stars"></div>
  </div>

  <div class = "flex" x-data = "{ days: 1, stars: 1 }">
    <select x-model = "days" @change = "updateTotal()">
      <option value = "1">1 day</option>
      <option value = "2">2 days</option>
      <option value = "3">3 days</option>
    </select>

    <select x-model = "stars" @change = "updateTotal()">
      <option value = "1">1 star</option>
      <option value = "2">2 stars</option>
      <option value = "3">3 stars</option>
    </select>

    <div class = "sum" x-text = "days * stars"></div>
  </div>

  <div x-text = "'Total: ' + total"></div>

  <script src = "https://cdn.jsdelivr.net/npm/alpinejs@3"></script>
  <script src = "https://code.jquery.com/jquery-3.6.0.min.js"></script>
  <script>
    function updateTotal() {
      var total = 0;
      $('.sum').each(function() {
        var value = parseInt($(this).text());
        if (!isNaN(value)) {
          total += value;
        }
      });
      Alpine.store('total', total);
    }

    $(document).ready(function() {
      updateTotal();
    });

    Alpine.data('example', () => ({
      total: Alpine.store('total'),

      mounted() {
        this.$watch('$refs.sum', () => {
          updateTotal();
          this.total = Alpine.store('total');
        });
      },
    }));
  </script>
</div>

Ответ принят как подходящий

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

<script defer src = "https://cdn.jsdelivr.net/npm/[email protected]/dist/cdn.min.js"></script>
<div x-data = "{ promos: {
                  promo1: {days: 1, stars: 1},
                  promo2: {days: 1, stars: 1},
                  promo3: {days: 1, stars: 1},
              },

              get total() {
                return Object.values(this.promos).reduce((acc, cur) => acc + cur.days*cur.stars, 0)
              }
  }">
  <div class = "flex">
    <select x-model.number = "promos.promo1.days">
      <option value = "1">1 day</option>
      <option value = "2">2 days</option>
      <option value = "3">3 days</option>
    </select>

    <select x-model.number = "promos.promo1.stars">
      <option value = "1">1 star</option>
      <option value = "2">2 stars</option>
      <option value = "3">3 stars</option>
    </select>

    <div class = "sum" x-text = "promos.promo1.days * promos.promo1.stars"></div>
  </div>

  <div class = "flex">
    <select x-model.number = "promos.promo2.days">
      <option value = "1">1 day</option>
      <option value = "2">2 days</option>
      <option value = "3">3 days</option>
    </select>

    <select x-model.number = "promos.promo2.stars">
      <option value = "1">1 star</option>
      <option value = "2">2 stars</option>
      <option value = "3">3 stars</option>
    </select>

    <div class = "sum" x-text = "promos.promo2.days * promos.promo2.stars"></div>
  </div>

  <div class = "flex">
    <select x-model.number = "promos.promo3.days">
      <option value = "1">1 day</option>
      <option value = "2">2 days</option>
      <option value = "3">3 days</option>
    </select>

    <select x-model.number = "promos.promo3.stars">
      <option value = "1">1 star</option>
      <option value = "2">2 stars</option>
      <option value = "3">3 stars</option>
    </select>

    <div class = "sum" x-text = "promos.promo3.days * promos.promo3.stars"></div>
  </div>

  <div x-text = "`Total: ${total}`"></div>
</div>

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