首页 > 解决方案 > 我不确定为什么我不能使用 .forEach() 更改我的 Class 对象的 .value 值

问题描述

我将所有骰子对象存储在 diceArray 数组中(我已经对此进行了测试并且知道它们已正确存储)。
我不知道为什么我不能循环遍历数组并更改每个对象的 .value, value。
我检查了按钮的 id,我知道它是正确的,所以我看不到我在这里缺少什么。
ps〜我目前没有控制台错误。

function randomNumber(min, max) {
  return Math.floor(Math.random() * (max - min) + min);
}
diceArray  = [];
const body = document.body;

class Die {
  constructor() {
    this.value = this.roll();
    this.div = `<div class="a-die d-flex align-items-center justify-content-center mx-4"><h1 class="die-text">${this.value}</h1></div>`;
    diceArray.push(this);
    $('#diceHolder').append(this.div);
  }
  roll = () => {
    return randomNumber(1, 7);
  }
  rollAll = () => {
    $(this.value).replaceWith(randomNumber(1, 7));
  }
}

$('#genDice').on('click', () => { let thisDie = new Die() });
$('#yahtzee').on('click', () => $('.die-text').text(randomNumber(1, 7)));

$('#rollDice').on('click', diceArray.forEach(val => {
  val.value = randomNumber(1, 7);
}));

标签: javascriptjqueryoop

解决方案


你期望这个模板...

this.div = `
<div class="a-die d-flex align-items-center justify-content-center mx-4">
  <h1 class="die-text">${this.value}</h1>
</div>`;

...成为“活”,每当价值发生this.value变化时都会自我更新。但这就是 HTML 的工作原理——这正是近年来所有这些数据绑定框架和库活跃起来的原因。

因此,除非您想开始深入研究这些内容,否则您必须自己实现这种“活力”。一种(相当直接的)方法是修改您的类以存储对 DOM 对象的引用(而不仅仅是一个普通的字符串):

this.value = this.roll();
this.$div = $(`<div class="a-die d-flex align-items-center justify-content-center mx-4"><h1 class="die-text">${this.value}</h1></div>`);
$('#diceHolder').append(this.$div);
diceArray.push(this);

Die...然后使用强制 DOM 使用当前值更新的方法来丰富类:

refreshView = () => {
  this.$div.find('h1').text(this.value);
}

之后,您可以直接在单击处理程序中更改值后调用此方法(请注意,它应该是一个正确的函数;现在您只调用一次 forEach):

$('#rollDice').on('click', () => diceArray.forEach(val => {
  val.value = randomNumber(1, 7);
  val.refreshView();
}));

这就是它的样子:

function randomNumber(min, max) {
  return Math.floor(Math.random() * (max - min) + min);
}
const diceArray  = [];
const body = document.body;

class Die {
  constructor() {
    this.value = this.roll();
    this.$div = $(`<div class="a-die d-flex align-items-center justify-content-center mx-4"><h1 class="die-text">${this.value}</h1></div>`);
    diceArray.push(this);
    $('#diceHolder').append(this.$div);
  }
  roll = () => {
    return randomNumber(1, 7);
  }
  refreshView = () => {
    this.$div.find('h1').text(this.value);
  }
  rollAll = () => {
    this.value = randomNumber(1, 7);
    this.refreshView();
  }
}

$('#genDice').on('click', () => { let thisDie = new Die() });
$('#yahtzee').on('click', () => $('.die-text').text(randomNumber(1, 7)));

$('#rollDice').on('click', () => diceArray.forEach(val => {
  // console.log(val);
  val.value = randomNumber(1, 7);
  val.refreshView();
}));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="diceHolder"></div>
<button id="genDice">Gen Dice</button>
<button id="rollDice">Reroll</button>

您可以获得更多创意,并组织您的代码,以便更新值始终触发 refreshView(例如,通过使用Proxy)。或者您可以跟踪任何事件,并重新检查绑定到 DOM 的每个值,在发生更改时触发重新渲染。最后,您可以强制您的代码用户避免直接修改对象,而只调用特定函数来更新它(将“refreshView”连接到该函数)。

但是,在这种情况下,您基本上开始自己重新实现这些框架。) 当你正在学习绳索时,这可能是一个好主意——但至少开始学习其中一个也可能是一个可靠的选择。


推荐阅读