在 AlpineJS 中事后刷新数据
Refreshing data after-the-fact in AlpineJS
我正在使用 Alpine 来显示将要更改的项目列表。但是我不知道如何告诉 Alpine 在服务器返回新项目后刷新项目列表:
<div x-data=" items() ">
<template x-for=" item in items " :key=" item ">
<div x-text=" item.name "></div>
</template>
</div>
第一个“批次”项目没问题,因为它们是硬编码在 items()
函数中的:
function items(){
return {
items: [
{ name: 'aaron' },
{ name: 'becky' },
{ name: 'claude' },
{ name: 'david' }
]
};
}
Alpine 之外的一些代码获取并接收一个全新的项目列表,我想显示该列表而不是原始列表。我不知道如何,或者目前是否可能。感谢您的指点。
有 3 种方法可以解决这个问题。
- 将提取移动到 Alpine.js 上下文中,以便它可以更新
this.items
function items(){
return {
items: [
{ name: 'aaron' },
{ name: 'becky' },
{ name: 'claude' },
{ name: 'david' }
],
updateItems() {
// something, likely using fetch('/your-data-url').then((res) => )
this.items = newItems;
}
};
}
- (不推荐)从您的 JavaScript 代码,访问
rootElement.__x.$data
并设置 __x.$data.items = someValue
<script>
// some other script on the page
// using querySelector assumes there's only 1 Alpine component
document.querySelector('[x-data]').__x.$data.items = [];
</script>
- 从您的 JavaScript 触发一个事件并从您的 Alpine.js 组件收听它。
更新 Alpine.js 组件,注意 x-on:items-load.window="items = $event.detail.items"
:
<div x-data=" items() " x-on:items-load.window="items = $event.detail.items">
<template x-for=" item in items " :key=" item ">
<div x-text=" item.name "></div>
</template>
</div>
触发自定义事件的代码,您需要填写负载。
<script>
let event = new CustomEvent("items-load", {
detail: {
items: []
}
});
window.dispatchEvent(event);
</script>
扩展 Hugo 的出色回答,我实现了一个简单的补丁方法,让您可以从外部更新应用的状态,同时保持其反应性:
<div x-data="app()" x-on:patch.window="patch">
<h1 x-text="headline"></h1>
</div>
function app(){
window.model = {
headline: "some initial value",
patch(payloadOrEvent){
if(payloadOrEvent instanceof CustomEvent){
for(const key in payloadOrEvent.detail){
this[key] = payloadOrEvent.detail[key];
}
}else{
window.dispatchEvent(new CustomEvent("patch", {
detail: payloadOrEvent
}));
}
}
};
return window.model;
}
在你的另一个不相关的脚本中你可以调用
window.model.patch({headline : 'a new value!'});
或者,如果您不想将 alpine 的数据模型分配给 window,您可以简单地触发事件,如上面 Hugo 的回答:
window.dispatchEvent(new CustomEvent("patch", {
detail: {headline : 'headline directly set by event!'}
}));
我正在使用 Alpine 来显示将要更改的项目列表。但是我不知道如何告诉 Alpine 在服务器返回新项目后刷新项目列表:
<div x-data=" items() ">
<template x-for=" item in items " :key=" item ">
<div x-text=" item.name "></div>
</template>
</div>
第一个“批次”项目没问题,因为它们是硬编码在 items()
函数中的:
function items(){
return {
items: [
{ name: 'aaron' },
{ name: 'becky' },
{ name: 'claude' },
{ name: 'david' }
]
};
}
Alpine 之外的一些代码获取并接收一个全新的项目列表,我想显示该列表而不是原始列表。我不知道如何,或者目前是否可能。感谢您的指点。
有 3 种方法可以解决这个问题。
- 将提取移动到 Alpine.js 上下文中,以便它可以更新
this.items
function items(){
return {
items: [
{ name: 'aaron' },
{ name: 'becky' },
{ name: 'claude' },
{ name: 'david' }
],
updateItems() {
// something, likely using fetch('/your-data-url').then((res) => )
this.items = newItems;
}
};
}
- (不推荐)从您的 JavaScript 代码,访问
rootElement.__x.$data
并设置__x.$data.items = someValue
<script>
// some other script on the page
// using querySelector assumes there's only 1 Alpine component
document.querySelector('[x-data]').__x.$data.items = [];
</script>
- 从您的 JavaScript 触发一个事件并从您的 Alpine.js 组件收听它。
更新 Alpine.js 组件,注意 x-on:items-load.window="items = $event.detail.items"
:
<div x-data=" items() " x-on:items-load.window="items = $event.detail.items">
<template x-for=" item in items " :key=" item ">
<div x-text=" item.name "></div>
</template>
</div>
触发自定义事件的代码,您需要填写负载。
<script>
let event = new CustomEvent("items-load", {
detail: {
items: []
}
});
window.dispatchEvent(event);
</script>
扩展 Hugo 的出色回答,我实现了一个简单的补丁方法,让您可以从外部更新应用的状态,同时保持其反应性:
<div x-data="app()" x-on:patch.window="patch">
<h1 x-text="headline"></h1>
</div>
function app(){
window.model = {
headline: "some initial value",
patch(payloadOrEvent){
if(payloadOrEvent instanceof CustomEvent){
for(const key in payloadOrEvent.detail){
this[key] = payloadOrEvent.detail[key];
}
}else{
window.dispatchEvent(new CustomEvent("patch", {
detail: payloadOrEvent
}));
}
}
};
return window.model;
}
在你的另一个不相关的脚本中你可以调用
window.model.patch({headline : 'a new value!'});
或者,如果您不想将 alpine 的数据模型分配给 window,您可以简单地触发事件,如上面 Hugo 的回答:
window.dispatchEvent(new CustomEvent("patch", {
detail: {headline : 'headline directly set by event!'}
}));