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

#javascript #html

Вопрос:

У меня есть объект из класса:

 class House {
    constructor(user, name, cost, level) {
        this.user = user;
        this.name = name;
        this.cost = cost;
        this.level = level;
    }

    get costValue() {
        return this.cost;
    }
    get levelValue() {
        return this.level;
    }

    setLevel = (newLevel) => {
        this.level = newLevel;
    }

    setCost = (newCost) => {
        this.cost = newCost;
    }

    levelUp = () => {
        if (this.user.materials >= this.cost) {
            this.user.subtractMaterials(this.cost);
            this.setLevel(this.level   1);
            this.setCost(this.cost * 1.25);
        }
    }

    canLevelUp = () => {
        return this.user.materials >= this.cost;
    }
}
 

И объект HTML

 const houseComponent = (houseObj) => {
    const house = document.createElement('div');
    house.className = 'house';

    const title = document.createElement('h2');
    title.innerHTML = houseObj.name;

    const level = document.createElement('p');
    level.innerHTML = `Level: ${houseObj.levelValue}`;

    const cost = document.createElement('p');
    cost.innerHTML = `Cost: ${houseObj.costValue}`;

    const button = document.createElement('button');
    button.textContent = 'Level Up';
    button.onclick = function() {
        if (houseObj.canLevelUp()) {
            houseObj.levelUp()
        }
    };

    house.appendChild(title);
    house.appendChild(level);
    house.appendChild(cost);
    house.appendChild(button);
    return house;
}
 

HTML отображается нормально, но при нажатии кнопки HTML не обновляется.
Если я консольно регистрирую дом и User , их значения обновляются правильно, просто не будут обновляться.

Как сделать так, чтобы HTML-элемент реагировал на объекты, которые он использует для его визуализации?

Только ванильный js, никаких рамок. Любая помощь будет очень признательна.

Комментарии:

1. Ожидаете ли вы или хотите обновить узлы DOM, отображающие значения?

2. Да, например, я хотел cost.innerHTML = 'Cost: ${houseObj.costValue}'; бы обновить, когда houseObj.costValue обновления

3. Вам потребуется, чтобы установщик, например, обновил соответствующий узел DOM или реализовал какой-либо шаблон наблюдателя.

4. итак, что-то вроде того, что при обновлении значения «повторно получите» элемент со значением и обновите его вручную? Нет никакого способа сделать это автоматически?

Ответ №1:

Обратите внимание, что нет прослушивателя для обновления level тега (я имею в виду p тег, который показывает level значение) для обновления innerHTML тега при levelUp(); вызове методов.

Вы только что изменили уровень houseObj , поэтому вам нужно изменить p тег при levelUp(); вызове метода, вот так:

  button.onclick = function() {
      if (houseObj.canLevelUp()) {
          houseObj.levelUp();
          level.innerHTML  =  `Level: ${houseObj.levelValue}`;
      }
  };
 
 class House {
  constructor(user,name,cost,level) {
      this.user = user;
      this.name = name;
      this.cost = cost;
      this.level = level;
  }

  get costValue() {
      return this.cost;
  }
  get levelValue() {
      return this.level;
  }

  setLevel = (newLevel) => {
      this.level = newLevel;
  }

  setCost = (newCost) => {
      this.cost = newCost;
  }

  levelUp = () => {
      if (this.user.materials >= this.cost) {
          //this.user.subtractMaterials(this.cost);
          this.setLevel(this.level   1);
          this.setCost(this.cost * 1.25);
      }
  }

  canLevelUp = () => {
      return this.user.materials >= this.cost;
  }
}


const houseComponent = (houseObj) => {
  const house = document.createElement('div');
  house.className = 'house';

  const title = document.createElement('h2');
  title.innerHTML = houseObj.name;

  const level = document.createElement('p');
  level.innerHTML = `Level: ${houseObj.levelValue}`;

  const cost = document.createElement('p');
  cost.innerHTML = `Cost: ${houseObj.costValue}`;

  const button = document.createElement('button');
  button.textContent = 'Level Up';
  button.onclick = function() {
      if (houseObj.canLevelUp()) {
          houseObj.levelUp();
          level.innerHTML  =  `Level: ${houseObj.levelValue}`;
      }
  };

  house.appendChild(title);
  house.appendChild(level);
  house.appendChild(cost);
  house.appendChild(button);
  return house;
}

var f = houseComponent(new House({materials:50},"name",10,1))
document.body.append(f);