# 使用 Alpine .+js 和 HTMX 的自动“-”更新部分更新器

<datetime class="hidden">2025-04-23T19:30</datetime>

<!--category-- Javascript, HTMX, Alpine.js, ASP.NET Core -->
# 一. 导言导言 导言 导言 导言

所以在一个工程项目中, 'Qs 变成一个序列\"," 我想添加部分能力到自动=-\更新给定的时间尺度@.}

我使用Alpine .js和HTMX.的方式,

[TOC]

# 所需资源所需资源所需资源所需资源 所需经费所需资源所需资源

所以我希望这个

1. 重新使用@ ;} 因此它应该简单, 自定义 - 足于自动\ MS K2\ {更新任何元素.} @
2. 它应尊重现有的Url参数
3. 在此情况下,它应该是可探测的服务器侧 (in ASPMS K1NET核心
4. 如果打开它, 应该启用它 *该终点的结束点* 仅此而已, 在请求中应该记住. {}
5. 当启用“ (” 时, 它应该立即进行更新。 因此用户知道它看起来像什么) }
6. 用户应能够关掉它
7. 在页面中添加“.”应该很简单。

考虑到这一点,我准备用Alpine.js和HTMX.建立一个小型的联署材料模块。

## 注注注注

您可以在没有“ ' @ on” 和“ I'}” 及“ MPK2@ remember” 的情况下进行自动更新, 只要使用 HTMX 即可 。
例如使用@; [HTMX 触发器 ](https://htmx.org/attributes/hx-trigger/) 您真的可以做很多东西吗? .

```html

<div id="campaignemail-request-list" hx-get="@Url.Action("List", "CampaignEmailRequest")" hx-trigger="every 30s" hx-swap="innerHTML">
    <partial name="_List" model="@Model"/>
</div>
```

感谢 [@ @ @ KhalidAbuhakmeh (哈立德阿布哈克梅)](https://khalidabuhakmeh.com/) 指出这一点时

此代码实际上使用此代码 `hx-trigger` 仅使用 Alpine @.js 配置 HTMX 属性@.}
与Alpine .}HTMX为何如此强大的组合 MS K2} HTMX处理所有服务器互动和 AJAX 请求 *,}而 Alpine <.}js 则处理客户端状态和交互性*. 200}你能否在Vanilla JS?} Sure,}中也这样做? 但你最后写出一套代码来做同样的事情

# 《刑法典》

此代码非常简洁, 包括两个主要部分 @;_JS模块@,}事件处理者和 HTML\.}

## 模块单元

该模块是一个简单的 JS 模块, 它使用 Alpine.js来管理自动的状态@ -update @ MS K2它使用本地存储以记住自定义的状态\ -}更新在请求之间的时间@.}

它接受参数 :

- `endpointId` -将更新元素的代号
- `actionUrl` - 用来更新元素的url
- `initialInterval` @ - 用于自动@ MS K1} 更新 date *\ ( 默认为 @ MPK3 秒@)

我们也可以看到它使用几把密钥“;” 用于本地存储,以记住自动“MS K1” 的状态。
你可以看到我用的是 `actionurl` 作为使此端点具体化的密钥的一部分 @ . @

```javascript
export function autoUpdateController(endpointId, actionUrl, initialInterval = 30) {
const keyPrefix = `autoUpdate:${actionUrl}`;
const enabledKey = `${keyPrefix}:enabled`;

    return {
        autoUpdate: false,
        interval: initialInterval,

        toggleAutoUpdate() {
            const el = document.getElementById(endpointId);
            if (!el) return;

            const url = new URL(window.location.href);
            const query = url.searchParams.toString();
            const fullUrl = query ? `${actionUrl}?${query}` : actionUrl;

            const wasPreviouslyEnabled = localStorage.getItem(enabledKey) === 'true';

            if (this.autoUpdate) {
                el.setAttribute('hx-trigger', `every ${this.interval}s`);
                el.setAttribute('hx-swap', 'innerHTML');
                el.setAttribute('hx-get', fullUrl);
                el.setAttribute('hx-headers', JSON.stringify({ AutoPoll: 'auto' }));

                localStorage.setItem(enabledKey, 'true');

                htmx.process(el); // rebind with updated attributes
                
                if (!wasPreviouslyEnabled) {
                    htmx.ajax('GET', fullUrl, {
                        target: el,
                        swap: 'innerHTML',
                        headers: {AutoPoll: 'auto'}
                    });
                }
            } else {
                el.removeAttribute('hx-trigger');
                el.removeAttribute('hx-get');
                el.removeAttribute('hx-swap');
                el.removeAttribute('hx-headers');

                localStorage.removeItem(enabledKey);
                htmx.process(el);
            }
        },

        init() {
            this.autoUpdate = localStorage.getItem(enabledKey) === 'true';
            this.toggleAutoUpdate();
        }
    };
}
```

### `toggleAutoUpdate()` 方法方法方法

此方法使用 HTMX @ . 来启用或禁用目标 HTML 元素的自动投票

### 行为行为

- 根据其 `endpointId`.
- 构建请求的 URL @ (`fullUrl`) 组合给定 `actionUrl` 使用当前页面@'查询字符串 @.
- 检查先前是否通过读取 `localStorage` @ (_ 良好, 在浏览器会话间被记住@).\ {}

#### 何时 `this.autoUpdate` 是 `true` @(i .e., 投票已启动@):

- 设置元素上的 HTMX 属性@: @%
  - `hx-trigger` 民意调查 `interval` 秒数秒
  - `hx-swap="innerHTML"` 以替换元素@’ @%s 内容
  - `hx-get` 指向投票地址
  - `hx-headers` 添加自定义 `"AutoPoll": "auto"` 头标题
- 保存启用状态 `localStorage`
- 呼吁呼吁 `htmx.process(el)` 让 HTMX 识别新属性
- 如果它先前不在@, @ 立即通过 HTMX 请求 `htmx.ajax()` 不依赖 HTMX 事件连接 )

#### 何时 `this.autoUpdate` 是 `false` @(i .e., 投票是残疾@):

- 删除上述 HTMX 属性
- 清除保存的设置 `localStorage`
- 呼吁呼吁 `htmx.process(el)` 重新更新 HTMX 行为

### 第一次启用时自动投放

我们这里还有一个分支 来进行自动操作 -polll 当第一次启用时\.

```javascript
const wasPreviouslyEnabled = localStorage.getItem(enabledKey) === 'true';
      if (!wasPreviouslyEnabled) {
                    htmx.ajax('GET', fullUrl, {
                        target: el,
                        swap: 'innerHTML',
                        headers: {AutoPoll: 'auto'}
                    });
                }
```

此操作执行 HTMX 向 `fullUrl` 并用响应来更新目标元素@.}这可用于向用户显示自动=-}当用户启用它时, 自动=MSK1}更新日期会是什么样子吗? @ .}

## 页眉

您将注意到, 我们还会发送 HTMX 信头及其请求@ .} 这很重要, 因为它能让我们检测到请求服务器的侧面 @ MS K2 *

```javascript
   el.setAttribute('hx-headers', JSON.stringify({ AutoPoll: 'auto' }));
headers: {AutoPoll: 'auto'}

```

在我的服务器侧端, 我检测到这个信头是使用

```csharp
 if (Request.Headers.TryGetValue("AutoPoll", out _))
        {
            
            
            var utcDate = DateTime.UtcNow;
            var parisTz = TimeZoneInfo.FindSystemTimeZoneById("Europe/Paris");
            var parisTime = TimeZoneInfo.ConvertTimeFromUtc(utcDate, parisTz);

            var timeStr = parisTime.ToString("yyyy-MM-dd HH:mm:ss");
              Response.ShowToast($"Auto Update Last updated: {timeStr} (paris)",true); 
         
            return PartialView("_List", requests);
        }
```

你看看,我只是找一个标题 `Request.Headers.TryGetValue("AutoPoll", out _)` 如果它在那里 我知道它是自动的-Pol要求的 .

然后我拿起法国客户的 Yei yime @(@it' @%s, 于是我转换成巴黎时间@)}并用时间显示一个祝酒词 @.{#

### 显示 toast

缩略 `ShowToast` 是一种简单的扩展方法,可以设定一个触发器来让 HTMX 显示一个烤面包消息@. @%

```csharp
    public static void ShowToast(this HttpResponse response, string message, bool success = true)
    {
        response.Headers.Append("HX-Trigger", JsonSerializer.Serialize(new
        {
            showToast = new
            {
                toast = message,
                issuccess =success
            }
        }));

    }
```

然后通过我的 HTMX 吐司元件检测到它,其中显示消息@. @%

```javascript
document.body.addEventListener("showToast", (event) => {
    const { toast, issuccess } = event.detail || {};
    const type = issuccess === false ? 'error' : 'success';
    showToast(toast || 'Done!', 3000, type);
});

```

然后,这需要我的吐司构成部分一。 [在此写入 ](https://www.mostlylucid.net/blog/showingtoastandswappingwithhtmx).

### 勾搭起来

在您的主控件“ most” 中连接此模块非常简单( M,Q)

```javascript
import './auto-actions';

window.autoUpdateController = autoUpdateController; //note this isn't strictly necessary but it makes it easier to use in the HTML


//Where we actually hook it up to Alpine.js
document.addEventListener('alpine:init', () => {
    Alpine.data('autoUpdate', function () {
        const endpointId = this.$el.dataset.endpointId;
        const actionUrl = this.$el.dataset.actionUrl;
        const interval = parseInt(this.$el.dataset.interval || '30', 10); // default to 30s

        return autoUpdateController(endpointId, actionUrl, interval);
    });
});

```

然后我们用ASP.NET Razor代码 :调用Init方法

## ASP.NET 剃须码

尽可能小的再用,雷泽代码很简单

您可以在这里看到我指定了 Alpine.js 数据属性来设置自动@ - update@.}

- x-data: 这里是我们设置阿尔卑斯山.js 数据对象@.的地方
- 这是自动 - 更新控制器的输入方法@.}
- x-on:change: 这里是我们称之为自动自动更新方法的地方 自动-update controlMS K4
- 这是要更新的元素的代号@ . @
- 数据@-action @-url: 这是用来更新元素的 URL {.}
- NAME OF TRANSLATORS (% 1)

您将看到我们设定目标 用于请求 `campaignemail-request-list` 元素\ . {这是将使用新内容更新的元素}.\ }
然后在页面中包括了某个地方。

当选中一个复选框时, 它会自动更新列表中的每一个“ 30” 秒@ MS K1

```html
            <div class=" px-4 py-2 bg-base-100 border border-base-300 rounded-box"
                x-data="autoUpdate()" 
                x-init="init"
                x-on:change="toggleAutoUpdate"
                data-endpoint-id="campaignemail-request-list"
                data-action-url="@Url.Action("List", "CampaignEmailRequest")"
                data-interval="30"
                >
                <label class="flex items-center gap-2">
                    <input type="checkbox" x-model="autoUpdate" class="toggle toggle-sm" />
                    <span class="label-text">
                        Auto update every <span x-text="$data.interval"></span>s
                    </span>
                </label>
            </div>

        <!-- Voucher List -->
        <div id="campaignemail-request-container">
            <div
                id="campaignemail-request-list">
                <partial name="_List" model="@Model"/>
            </div>
        </div>
```

# 在结论中的结论

并且“'”它是一个很简单的右转 “.”使用 HTMX和Alpine .js来创建一个简单的自动=-}更新组件 从 ASP\.NET Core@.>我们很容易就能用到