AlpineJS не инициализируется в динамически загружаемом контенте
Я создаю пользовательский виджет выбора с возможностью поиска в моем приложении django.
При возврате шаблона все нормально, однако Alpine не инициализируется, когда я динамически отображаю это поле внутри модала. Я использую HTMX для выполнения ajax-запроса; Django отвечает шаблоном, и этот шаблон вставляется в DOM/модала.
То, что я пробовал
- Добавление данных моего
Alpine.data
непосредственно в x-data. Это работает, но хотелось бы избежать этого, если возможно .
- Хакерские способы попробовать инициализировать Alpine, но не работает (возможно, я что-то упустил)
- Подключение к событию HTMX beforeSwap, чтобы попытаться загрузить JS перед шаблоном (безрезультатно)
Если кто-нибудь знает, как это исправить, буду очень признателен
Шаблон
<div x-data="autocomplete" x-init="init('{{ widget.value }}')" class="relative">
# template stuff...
</div>
Script
document.addEventListener('alpine:init', () => {
Alpine.data('autocomplete', () => ({
open: false,
selectedValue: '',
init(value) {
if (!['None'].includes(value)) {
this.selectedValue = value;
}
},
# functions used inside the template...
}));
});
Вам следует лучше объяснить на примерах контекст и то, что вы пробовали, запрос неясен
Я вижу ошибку в том, что вы инициализируете свойство selectedValue с помощью директивы x-init, которая вызывает метод init(): в AlpineJs 3 метод init() вызывается автоматически, как только объект создается, поэтому в результате он запускается дважды: один раз сам по себе и один раз вместе с вашим x-init.
Вы можете убедиться в этом, просто добавив console.log() в init():
document.addEventListener('alpine:init', () => {
Alpine.data('autocomplete', () => ({
open: false,
selectedValue: '',
init(value) {
console.log ('Tadah!', Date.now());
if (!['None'].includes (value)) {
this.selectedValue = value;
}
}
}));
});
Правильно передавать начальный параметр с помощью x-data, как объясняется здесь:
<div x-data="autocomplete('{{ widget.value }}')" class="relative">
.....
</div>
<script>
document.addEventListener('alpine:init', () => {
Alpine.data('autocomplete', (value) => ({
open: false,
selectedValue: '',
init() {
if (!['None'].includes (value)) {
this.selectedValue = value;
}
}
}));
});
</script>
Однако можно переименовать метод init(), например, в myInit() и вызывать его с помощью директивы x-init, но мне это кажется несколько многословным