Директива ref в библиотеке FAST Element является
инструментом для прямого получения ссылок на DOM-элементы или компоненты
внутри шаблона. Она позволяет управлять элементами после их создания,
предоставляя доступ к их свойствам, методам и событиям без необходимости
поиска через стандартные DOM-методы (querySelector,
getElementById и т.п.).
refСинтаксис директивы прост: в шаблоне FAST Element к элементу или
компоненту добавляется атрибут ref с функцией, которая
принимает один аргумент — ссылку на DOM-узел или компонент.
import { FASTElement, html, ref } from "@microsoft/fast-element";
class MyComponent extends FASTElement {
buttonElement;
handleButtonRef = (el) => {
this.buttonElement = el;
}
}
MyComponent.template = html<MyComponent>`
<button ${ref(x => x.handleButtonRef)}>Нажми меня</button>
`;
В этом примере функция handleButtonRef получает ссылку
на элемент <button> и сохраняет её в свойство
buttonElement. После этого можно напрямую работать с
кнопкой в методах компонента, например вызывать методы, изменять
атрибуты или добавлять обработчики событий.
Ключевой момент: функция, переданная в
ref, вызывается один раз при создании
элемента и затем при удалении элемента с
передачей null. Это позволяет безопасно освобождать ссылки
на элементы.
ref не ограничивается стандартными HTML-элементами. Она
также работает с кастомными элементами, созданными на основе FAST
Element или других веб-компонентов.
class CustomInput extends FASTElement {
focusInput() {
this.shadowRoot.querySelector("input").focus();
}
}
class FormComponent extends FASTElement {
inputRef;
handleInputRef = (el) => {
this.inputRef = el;
}
}
FormComponent.template = html<FormComponent>`
<custom-input ${ref(x => x.handleInputRef)}></custom-input>
<button @click="${x => x.inputRef.focusInput()}">Фокус на инпут</button>
`;
В этом примере ref позволяет вызвать метод кастомного
компонента напрямую, без необходимости искать его в DOM.
ref может быть использована и для динамических
элементов, например, в циклах repeat. Каждый элемент
получает собственную ссылку, что позволяет управлять отдельными
экземплярами.
import { repeat } from "@microsoft/fast-element";
class ItemList extends FASTElement {
items = ["A", "B", "C"];
itemRefs = [];
handleItemRef = (el, index) => {
this.itemRefs[index] = el;
}
}
ItemList.template = html<ItemList>`
<ul>
${repeat(x => x.items, html<ItemList>`
<li ${ref((el, c, index) => x.handleItemRef(el, index))}>${x => x}</li>
`)}
</ul>
`;
После рендера массив itemRefs содержит ссылки на все
<li> элементы, позволяя программно управлять их
состоянием или стилями.
Важно учитывать, что при удалении элемента из DOM функция, переданная
в ref, вызывается с аргументом null. Это
позволяет корректно освобождать ресурсы и предотвращает утечки
памяти:
handleButtonRef = (el) => {
this.buttonElement = el;
if (!el) {
console.log("Элемент удалён из DOM");
}
};
ref от стандартных методов доступа к DOMrepeat).ref
сохраняет ссылки в свойствах класса, можно использовать строгую
типизацию.ref для элементов, с которыми требуется
прямое взаимодействие (изменение состояния, вызов методов).${x => x.value}), чтобы не усложнять код.repeat контролировать индекс, чтобы избежать
перезаписи ссылок при обновлении списка.ref при удалении элементов, если
нужно управлять ресурсами вручную (например, таймерами или слушателями
событий).ref является ключевым инструментом для эффективного
управления DOM в FAST Element, обеспечивая прямой доступ к элементам и
компонентам при строгой интеграции с жизненным циклом шаблонов. Она
сочетает удобство с безопасностью, особенно при работе с динамическими
интерфейсами и кастомными элементами.