Я создал тостер AlpineJs и хочу запустить его из кода JavaScript, чтобы вызывать его из любого места.
Я пытался обновить магазин, но он не работает. Чего мне не хватает?
$("#triggerBtn").on("click", function(){ //that just an example with jquery
Alpine.store('toast',{type:"danger",message:"hello",visible:true});
})
document.addEventListener("alpine:init",()=>{
Alpine.store("toast",{type:null,message:null,alerts:[]});
Alpine.data('toast', () => ({
type:null,
message:null,
alerts:[],
init(){
var $store = Alpine.store("toast");
this.type = $store.type;
this.message = $store.message;
this.alerts = $store.alerts;
var icon = "fa fa-info-circle text-info-600";
this.alerts.push(
{
icon:icon,
message:this.message,
visible:true
}
Alpine.store('toast').alerts = this.alerts;
},
close(){
this.show=false
}
}))
})
<div x-data = "toast">
<template x-for = "alert in $store.toast.alerts">
<div x-show = "alert.visible" id = "liveToastAlpine"
class = "mb-3 z-40 drop-shadow-xl flex items-center w-full max-w-xs p-4 text-gray-500 bg-white rounded-lg"
role = "alert">
<div
class = "inline-flex items-center justify-center flex-shrink-0 w-8 h-8 text-info-500 bg-info-100 rounded-lg dark:bg-info-700 dark:text-info-200">
<i x-bind:class = "alert.icon" class = "fas"></i>
</div>
<div class = "ms-3 text-sm font-normal" x-text = "alert.message"></div>
<button type = "button" class = "ms-auto -mx-1.5 -my-1.5 bg-white text-gray-400 hover:text-gray-900 rounded-lg"
data-dismiss-target = "#liveToastTemplate" aria-label = "Close" @click = "alert.visible=false">
<span class = "sr-only">Close</span>
<i class = "fas fa-times"></i>
</button>
</div>
</template>
</div>
Нет необходимости полагаться на всплывающий объект для управления, поскольку цикл for может полагаться непосредственно на хранилище.
Обратите внимание, что волшебное свойство $store уже определено в Alpine, поэтому не следует объявлять переменные с одинаковым именем.
Поскольку хранилище позволяет добавлять методы взаимодействия с данными, возможное решение — переместить логику туда:
<div>
<div class = "m-2">
<button id = "triggerBtn"
class = "bg-blue-500 hover:bg-blue-700 text-white py-2 px-4 rounded"
>
New alert
</button>
</div>
<div x-data>
<template x-for = "(alert, index) in $store.toast.alerts" :key = "alert.key">
<div class = "mb-3 z-40 drop-shadow-xl flex items-center justify-around w-full max-w-xs p-4 rounded-lg"
:class = "{'bg-green-100 text-green-800': alert.type == 'info',
'bg-yellow-100 text-yellow-800': alert.type == 'warn',
'bg-red-100 text-red-800': alert.type == 'error'
}"
role = "alert"
>
<div class = "inline-flex rounded-lg">
<i x-bind:class = "alert.icon" class = "fas"></i>
</div>
<div class = "ms-3 text-sm font-normal"
x-text = "alert.message"
>
</div>
<button type = "button"
class = "p-1 rounded-lg"
:class = "{'text-green-900 hover:text-green-600': alert.type == 'info',
'text-yellow-900 hover:text-yellow-600': alert.type == 'warn',
'text-red-900 hover:text-red-600': alert.type == 'error'
}"
aria-label = "Close"
@click = "$store.toast.remove(index)"
>
<span class = "sr-only">
Close
</span>
<i class = "fas fa-times"></i>
</button>
</div>
</template>
</div>
</div>
<script>
// this is for testing
window.alertTypes = [
{message: "Info message", type: "info"},
{message: "Warning message", type: "warn"},
{message: "Error message", type: "error"},
];
document.getElementById("triggerBtn").addEventListener("click", function () {
const {message, type} = window.alertTypes[Math.floor(Math.random() * 3)]; // the message is set randomly for testing
Alpine.store("toast").add(message, type);
});
document.addEventListener("alpine:init", () => {
Alpine.store ("toast", {
alerts: [],
add: function (message = "", type = "info") {
this.alerts.push ({type: type, message: message, key: Date.now()})
},
remove: function (index) {
this.alerts.splice(index, 1);
}
});
});
</script>
Вместо того, чтобы скрывать сообщения, в моем решении я решил удалить связанную строку из массива, поэтому я удалил видимое свойство, но добавил ключевое свойство (которое имеет уникальное значение, полученное из даты), чтобы разрешить цикл x-for. чтобы понять, что было добавлено или удалено
Я также добавил простое управление цветами в зависимости от типа оповещения.
В целях тестирования я вставил глобальный список значений и кнопку, которая использует JavaScript, чтобы взять из него случайное значение и добавить его к показанным оповещениям.
Если коротко, то запуск отображения сообщения реализован добавлением строки через javascript в список, хранящийся в магазине Alpine.
Здесьдокументация для магазина Alpine
проверено и работает спасибо