Создание собственных делегированных свойств

Bliss.js предоставляет мощный механизм работы с DOM, позволяя создавать делегированные свойства, которые упрощают управление элементами, их состоянием и поведением. Делегированные свойства — это свойства объектов DOM, которые автоматически связываются с методами или атрибутами элементов, обеспечивая прозрачный доступ и обновление значений.


Основы делегированных свойств

Делегированные свойства в Bliss.js создаются с помощью метода $.delegateProperty. Суть механизма заключается в том, что свойство объекта не хранит значение локально, а передаёт чтение и запись соответствующему элементу или функции.

Простейший пример делегирования:

let button = $.create('button', { text: 'Click me' });

$.delegateProperty(button, 'label', {
    get() {
        return this.textContent;
    },
    set(value) {
        this.textContent = value;
    }
});

console.log(button.label); // Click me
button.label = 'New Label';
console.log(button.textContent); // New Label

Здесь свойство label не хранит значение самостоятельно. Его значение всегда синхронизировано с textContent кнопки. Такой подход позволяет создавать виртуальные свойства, отражающие реальное состояние DOM.


Настройка делегирования через селекторы и вложенные элементы

Bliss.js позволяет делегировать свойства не только самому элементу, но и его потомкам. Это особенно полезно для сложных компонентов:

let card = $.create('div', { html: '<h2></h2><p></p>' });

$.delegateProperty(card, 'title', {
    get() {
        return this.querySelector('h2').textContent;
    },
    set(value) {
        this.querySelector('h2').textContent = value;
    }
});

$.delegateProperty(card, 'description', {
    get() {
        return this.querySelector('p').textContent;
    },
    set(value) {
        this.querySelector('p').textContent = value;
    }
});

card.title = 'Card Title';
card.description = 'Detailed description';

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


Делегирование с использованием функций и вычисляемых значений

Свойства могут делегироваться не только к DOM-атрибутам, но и к вычисляемым значениям. Например, для динамического состояния:

let counter = $.create('span', { text: '0' });
let state = { value: 0 };

$.delegateProperty(counter, 'count', {
    get() {
        return state.value;
    },
    set(val) {
        state.value = val;
        this.textContent = val;
    }
});

counter.count = 5;
console.log(counter.textContent); // 5

Такое делегирование полезно для реализации реактивного поведения без использования внешних библиотек.


Связь с событиями и автоматическое обновление

Bliss.js позволяет связать делегированные свойства с событиями DOM, чтобы они автоматически обновлялись при изменении состояния:

let input = $.create('input', { type: 'text', value: 'Hello' });

$.delegateProperty(input, 'valueProp', {
    get() {
        return this.value;
    },
    set(val) {
        this.value = val;
    }
});

input.addEventListener('input', () => {
    console.log('Текущее значение:', input.valueProp);
});

Каждое изменение поля ввода немедленно отражается в делегированном свойстве, что облегчает синхронизацию интерфейса и данных.


Динамическое добавление делегированных свойств

Bliss.js поддерживает добавление свойств на лету, что позволяет строить компоненты с настраиваемыми интерфейсами:

function createWidget() {
    let widget = $.create('div', { class: 'widget' });
    
    $.delegateProperty(widget, 'status', {
        get() {
            return this.dataset.status || 'inactive';
        },
        set(val) {
            this.dataset.status = val;
        }
    });
    
    return widget;
}

let myWidget = createWidget();
myWidget.status = 'active';
console.log(myWidget.dataset.status); // active

Использование dataset в качестве хранилища обеспечивает сохранение состояния между обновлениями DOM и упрощает стилизацию через CSS.


Совмещение делегированных свойств и методов

Делегированные свойства можно использовать вместе с методами для построения полностью управляемых компонентов:

let toggle = $.create('button', { text: 'OFF' });

$.delegateProperty(toggle, 'active', {
    get() {
        return this.classList.contains('active');
    },
    set(val) {
        if(val) this.classList.add('active');
        else this.classList.remove('active');
        this.textContent = val ? 'ON' : 'OFF';
    }
});

toggle.addEventListener('click', () => toggle.active = !toggle.active);

Свойство active управляет сразу несколькими аспектами кнопки: классом и текстом, что делает компонент самодостаточным и легко расширяемым.


Принципы построения надежных делегированных свойств

  1. Ясная область делегирования — нужно точно определить, к какому элементу или атрибуту будет привязано свойство.
  2. Согласованность get и set — значения, возвращаемые геттером, должны корректно обрабатываться сеттером.
  3. Изоляция состояния — делегированные свойства не должны напрямую зависеть от внешних глобальных переменных, чтобы компонент оставался независимым.
  4. Поддержка событий — при необходимости синхронизации с внешними событиями, геттер и сеттер должны корректно реагировать на изменения DOM.

Создание собственных делегированных свойств в Bliss.js обеспечивает высокую читаемость, модульность и реактивность компонентов, позволяя строить сложные интерфейсы с минимальным количеством кода и максимальной поддерживаемостью.