Обновление переменных в шаблонных строках
Итак, есть у меня массив строк:
const VEGETABLE_MESSAGE = [
`Clean vegetable garden: ${VEGETABLE_GARDEN.building}%`,
`Seeds planted: ${VEGETABLE_GARDEN.seedPlant} seeds`,
`Collect the harvest: ${VEGETABLE_GARDEN.harvesting} %`,
'<span style="color:red">You forgot to water the seeds, the entire harvest was lost!</span>',
'<span style="color:red">Water seeds: no</span>',
'<span style="color:green">Water seeds: yes</span>',
];
есть вывод необходимой строки:
let VEGETABLE_GARDEN = {
building: 0,}
const VG = VEGETABLE_GARDEN
function mes() {
if (VG.building < 100) {
mesID = 0
} else if (VG.seedPlant < 100) {
mesID = 1
} else if (VG.harvestDay == 0) {
mesID = 2
} else if (VG.seedDie == 1) {
mesID = 3
} else {
mesID = waterMesVG();
}
document.getElementById('massageVG').innerHTML = VEGETABLE_MESSAGE[mesID];
}
mes() // итог будет: `Clean vegetable garden: 0 %`
// далее я выполняю некоторые действия и значение VEGETABLE_GARDEN.building меняется, например:
VEGETABLE_GARDEN.building = 15
// но при повтором вызове mes()
mes() // итог будет все равно `Clean vegetable garden: 0 %` вместо `Clean vegetable garden: 15 %`. Это и есть моя проблема.
// если же поместить VEGETABLE_MESSAGE в mes() то все будет прекрасно работать, однако это неудобно в силу ниже описанных проблем. Поэтому мне нужно, чтобы VEGETABLE_MESSAGE оставался за пределами исполняемой функции.
И вот значит какая проблема: если я обьявляю массив VEGETABLE_MESSAGE внутри функции публикации строки, то переменная ${VEGETABLE_GARDEN.building} и другие подобные переменные без проблем обновляются и публикуются как надо, но стоит мне вынести этот массив за пределы функции, обновления прекращаются.
Как я понимаю, проблема в том, что эти функции считывают значение переменных лишь при первом запуске и все. Итак, вопрос, как можно заставить переменные в таких строках обновляться за пределами вызываемой функции, например, при изменении значения самой переменной? Просто у меня такого текста довольно много и мне хотелось бы собрать его в одном месте, чтобы не лазить по всему коду в случае, например, если его нужно будет перевести на другой язык. Буду признателен за помощь и разьяснение того, как можно справиться с подобной проблемой.
Ответы (2 шт):
Шаблонная строка это безымянная функция, которая вызывается в момент объявления, вычисляется и результат вычисления подставляется на место самой строки. В вашем случае все строки будут вычислены в момент объявления const VEGETABLE_MESSAGE и больше меняться не будут. Так сделано чтобы программист мог контролировать что именно и когда будет вычислено. Если вы хотите вычислять одну шаблонную строку много раз, её надо именно вычислять много раз. Скажем, поместить в функцию, которую вы будете вызывать в момент, когда данные готовы:
const vegetableMessage = (vegetableGarden, messageId) => {
switch (messageId) {
case 0: return `Clean vegetable garden: ${vegetableGarden.building}%`;
case 1: return `Seeds planted: ${vegetableGarden.seedPlant} seeds`;
case 2: return `Collect the harvest: ${vegetableGarden.harvesting} %`;
case 3: return '<span style="color:red">You forgot to water the seeds, the entire harvest was lost!</span>';
case 4: return '<span style="color:red">Water seeds: no</span>';
case 5: return '<span style="color:green">Water seeds: yes</span>';
}
};
...
document.getElementById('massageVG').innerHTML = vegetableMessage(VEGETABLE_GARDEN, mesID);
P.S. Я отказался от массива, что бы не вычислять много строк, когда нужна только одна.
В очередной раз убедился, что правильно поставленный вопрос много чего значит. Я прицепился к тому, что работаю с шаблонными строками, но по факту мне нужно было лишь настроить обновление переменной, если ее значение менялось, при публикации указанной строки.
Таким образом, я нашел следующее решение данной проблемы: Я просто вынес все переменные за пределы строки и вернул их в функцию, а в строках добавил хтмл-элемент <span> с уникальным id. Далее, при публикации нужной строки, внутри функции я просто записывал текущее значение в указанный <span>:
/*
------------- Вот так было -----------------------
const VEGETABLE_MESSAGE = [
`Clean vegetable garden: ${VEGETABLE_GARDEN.building}%`,
`Seeds planted: ${VEGETABLE_GARDEN.seedPlant} seeds`,
`Collect the harvest: ${VEGETABLE_GARDEN.harvesting} %`,
'<span style="color:red">You forgot to water the seeds, the entire harvest was lost!</span>',
'<span style="color:red">Water seeds: no</span>',
'<span style="color:green">Water seeds: yes</span>',
];
-------------- Вот так стало -----------------------------
*/
const VEGETABLE_MESSAGE = [
'Clean vegetable garden: <span id="span_VG" style="color:red"></span>%',
'Seeds planted: <span id="span_VG" style="color:red"></span> seeds',
'Collect the harvest: <span id="span_VG" style="color:red"></span> %',
'<span style="color:red">You forgot to water the seeds, the entire harvest was lost!</span>',
'<span style="color:red">Water seeds: no</span>',
'<span style="color:green">Water seeds: yes</span>',
];
let VEGETABLE_GARDEN = {
building: 0,}
let x;
const VG = VEGETABLE_GARDEN
function mes() {
if (VG.building < 100) {
mesID = 0
x = VG.building // здесь присваиваем обновленное значение
} else if (VG.seedPlant < 100) {
mesID = 1
} else if (VG.harvestDay == 0) {
mesID = 2
} else if (VG.seedDie == 1) {
mesID = 3
} else {
mesID = waterMesVG();
}
document.getElementById('massageVG').innerHTML = VEGETABLE_MESSAGE[mesID];
if (x != null) { // если переменная не пустая, публикуем ее.
document.getElementById('span_VG').innerHTML = x;
}
}
VEGETABLE_GARDEN.building = 0
mes() // Clean vegetable garden: 0%
VEGETABLE_GARDEN.building = 15
mes() // Clean vegetable garden: 15%