Неужели это невозможно, если использовать функцию se t defineProperty для фактической установки значения свойства?
Я хочу реализовать двустороннее связывание данных (как в Angular или Vue) с использованием ванильного JavaScript.
Представление для моделирования части, которую я могу использовать, добавляет входной слушатель события, и модель для просмотра части, я хочу использовать функцию set Object.defineProperty.
В функции set defineProperty мне нужно изменить значение представления и установить значение свойства, но это вызовет "Превышен максимальный размер стека вызовов", потому что set property value
будет рекурсивно работать снова и снова.
Теперь вопрос: есть ли способ, которым я могу одновременно использовать функцию set и устанавливать значение ее свойства одновременно?
Теперь мой код:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>2 Way Data Binding</title>
</head>
<body>
text: <input id="text" class="text" type="text">
</body>
<script type="text/javascript">
var input = document.querySelector("#text");
var data = {};
Object.defineProperty(data, "text", {
get: function(){
return input.value
},
set: function(newValue){
input.value = newValue;
// data.text = newValue; // <------ this is the problem
}
})
input.input = function(){
data.text = data.text;
}
</script>
</html>
2 ответа
Ответить на ваш вопрос - нет. Если у вас есть сеттер, вы не можете развернуться и установить значение без зацикливания. Альтернатива состоит в том, чтобы иметь частную собственность на объекте, который только get()
а также set()
методы будут взаимодействовать с. Внешний мир будет использовать только те свойства, которые имеют геттеры / сеттеры.
Не уверен, что это отличный способ реализации связывания, но это способ создать видимость использования установщика для установки свойства:
const data = {
// _text is the source of truth
_text: "some text",
get text() {
return this._text
},
set text(newValue) {
input.value = newValue;
this._text = newValue;
}
};
const input = {
value: data.text
}
// original value
console.log(data.text)
console.log(input.value)
// change it
data.text = "other text"
console.log(data.text)
console.log(input.value)
В функции установки мне нужно установить значение свойства, но оно вызовет "Превышен максимальный размер стека вызовов", потому что значение установленного свойства будет рекурсивно выполняться снова и снова.
Да. Не делай этого. Настройка input.value
достаточно, получатель уже сообщит новое значение.
когда я console.log моя модель представления (в моем коде выше это данные), результатом является {} (пустой объект). Скажем, если я хочу повторить модель представления, это невозможно сделать.
Ну, это совсем другая проблема. Что можно легко решить, сделав перечисляемое свойство:
var input = document.querySelector("#text");
var data = {};
Object.defineProperty(data, "text", {
enumerable: true,
get: function(){
return input.value
},
set: function(newValue){
input.value = newValue;
}
});
console.log(data);