Это моя первая разработка с использованием html / javascript, и поскольку моя предыдущая карьера заключалась в программировании самолетов, все это кажется очень странным!
Итак ... Я взял Raspberry Pi и решил разработать серверное / клиентское программное обеспечение, чтобы я мог управлять своим садовым освещением и водными системами со своего мобильного телефона с помощью системы Wi-Fi.
Теперь я могу включать и выключать все огни и насосы в саду с любого мобильного телефона.
Сейчас я дорабатываю программное обеспечение, и этот простой элемент поставил меня в тупик. Когда пользователь включает функцию воды, я хочу, чтобы сервер отключал функцию воды, когда истекли минуты, установленные пользователем.
В html есть:
<p>
<input type = "checkbox" id = "waterFeatureZenGarden">
<label for = "waterFeatureZenGarden">Water Feature Zen Garden</label>
<input type = "number" min = "1" max = "180" value = "60" id = "waterFeatureZenGardenTimer">
</p>
мой Java Script на странице html имеет:
<script>
var socket = io(); //load socket.io-client and connect to the host that serves the page
window.addEventListener("load", function(){ //when page loads
var gateStatus = document.getElementById("gate");
var getWFZG = document.getElementById("WaterFeatureZenGarden");
var getWLZG = document.getElementById("WallLightsZenGarden");
var getLLZG = document.getElementById("LanternLightsZenGarden");
getWFZG.addEventListener("change", function() {
socket.emit("WaterFeatureZenGarden", Number(this.checked));
socket.emit("WaterFeatureZenGardenTimer", Number(this.value));
});
Мой серверный код получает события socket.emit, как показано ниже:
socket.on('waterFeatureZenGarden', function(data) {
wFZGvalue = data;
if (wFZGvalue != onWFZG.readSync()) {
onWFZG.writeSync(wFZGvalue); //turn pump on/off
}
});
socket.on('waterFeatureZenGardenTimer', function(data) {
wFZGTvalue = data;
// code will go here to start timer for how long the pump will run
console.info(wFZGTvalue); // added this line to see what wFZGTvalue is
});
Консоль показывает, что значение wFZGTvalue равно нулю.
Что я не так? Это на стороне сервера или на стороне клиента?
Если я изменю js на стороне клиента на:
socket.emit("waterFeatureZenGardenTimer", 100);
Сервер получает «100», поэтому кажется, что я неправильно обращаюсь к элементу html, но я получаю флажки для всех функций включения и выключения.
Спасибо



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Когда вы получаете доступ к this.value внутри слушателя, this ссылается на:
<input type = "checkbox" id = "waterFeatureZenGarden">
И это не имеет значения.
Вы можете получить таймер:
var timer = document.getElementById("WaterFeatureZenGardenTimer");
А затем возьмем значение таймеров:
socket.emit("timer", timer.value);
Теперь на стороне сервера вы можете определить глобальную переменную, в которой хранится ваш таймер:
let timer;
Затем, когда вы получите запрос времени клиента, вы можете убить текущий тайм-аут и установить новый:
if (timer) clearTimeout(timer);
timer = setTimeout(function(){
onWFZG.writeSync("0");
}, +userValue * 60 * 1000);
О серверной части: возможно, сейчас самое время познакомиться с подъемом. Если вы используете timer в качестве глобальной переменной, ее положение очень важно. (let в этом отношении ведет себя иначе, чем var). Кроме того, передача цифры 0 в writeSync кажется более логичным подходом, чем передача строки. Наконец-то я считаю, что плюс перед userValue - это опечатка?
@bram vanroy нет, не совсем. let также поднят, но у него есть временная мертвая зона, однако код в обработчике определенно будет исключен из определения таймера после, независимо от его положения. Мы не можем сказать, берет ли writeSync строку или нет, я думаю, что обе версии разумны. И нет, знак плюса - это унарный плюс, потому что я ненавижу предполагаемое приведение типов.
Jonas, Большое спасибо, что исправили. Похоже, мне нужно больше прочитать об 'this.xxx', поскольку я этого явно не понял. Со всеми другими комментариями от вас и Брэма я учту и внесу некоторые изменения.
В вашем window.addEventListener вам нужно получить входное значение, например
var timerValue = document.getElementById("waterFeatureZenGardenTimer").value;
а затем передайте это значение timerValue как
socket.emit("WaterFeatureZenGardenTimer", timerValue);
Каллешвар, спасибо за ваш вклад, только что попробовал, и это работает! Мне кажется, что мне нужно больше узнать о html, поскольку во многих отношениях JS более или менее соответствует типу кода, с которым я уже знаком, просто нужно привыкнуть к синтаксису.
Классный проект! Несколько вещей. Поскольку вы только начинаете изучать JS, возможно, лучше сразу же сесть на лодку ES6 - это новейшая итерация в Javascript, и в ней представлены некоторые интересные вещи, такие как стрелочные функции, константы, объектно ориентированный объект и т. д. Кроме того, если вы хотите запускать код при загрузке DOM, используйте document.addEventListener("DOMContentLoaded"). Наконец, в JS обычно используются имена lowerCamelCase для функций и переменных.
Что касается вашего кода, похоже, вам нужно значение таймера, а не флажка, на который ссылается this, поэтому добавьте также переменную для этого. Я не уверен, почему вы разбираете флажок, отмеченный как Number (), но я оставил его там, потому что не уверен, зачем вам это нужно.
const socket = io();
document.addEventListener("DOMContentLoaded", () => {
const gateStatus = document.querySelector("#gate"),
wfzg = document.querySelector("#WaterFeatureZenGarden"),
wfzgt = document.querySelector("#WaterFeatureZenGardenTimer"),
wlzg = document.querySelector("#WallLightsZenGarden"),
llzg = document.querySelector("#LanternLightsZenGarden");
getWFZG.addEventListener("change", function() {
socket.emit("WaterFeatureZenGarden", Number(this.checked));
socket.emit("WaterFeatureZenGardenTimer", wfzgt.value);
});
});
Спасибо, Брэм. Заглянем в лодку ES6. Будет ли это означать полное изменение кода или незначительные корректировки. Что касается причины, по которой при синтаксическом анализе флажок отмечен как Число (), это потому, что я узнал, как установить сервер и клиент на www.w3schools.com.
Добро пожаловать в SO :)