0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【ASP.NET初心者が学んでみた】第7章:非同期通信(AJAX)を使ってページを再読み込みせず更新してみる 〜 fetch() × Controller で動きのあるアプリへ 〜

0
Posted at

🏁 はじめに

前回(第6章:Bootstrapでデザインを整えてみる)では、UIをきれいに整えました。
今回はさらに一歩進んで、ページを再読み込みせずデータを更新する「非同期通信(AJAX)」 に挑戦します。

🎯 今回のゴール

「完了」ボタンを押すと、ページをリロードせずに状態を更新できるようにする

最終的な動き👇

✅ ボタンを押す → DB更新 → ページを再読み込みせず「完了!」と反映

🧩 Step 1:非同期通信とは?

通常、フォーム送信などはサーバーにリクエストを送るたびにページ全体が再読み込みされます。
非同期通信(AJAX)を使うと、JavaScript経由で一部データだけをサーバーとやり取りできます。

通信方式 特徴
同期通信(従来) ページ全体を再読み込み
非同期通信(AJAX) 必要な部分だけ更新できる(ユーザー体験UP!)

⚙️ Step 2:Todoモデルに完了フラグを追加

Models/Todo.cs に新しいプロパティを追加します。

public bool IsDone { get; set; } = false;

この変更をDBに反映させるため、マイグレーションを実行します。

Add-Migration AddIsDone
Update-Database

🧠 Step 3:ControllerにAPIメソッドを追加

TodosController に新しいアクションを追加します👇

[HttpPost]
public IActionResult ToggleDone(int id)
{
    var todo = _context.Todos.Find(id);
    if (todo == null) return NotFound();

    todo.IsDone = !todo.IsDone;
    _context.SaveChanges();

    return Json(new { success = true, isDone = todo.IsDone });
}

ポイント:

  • Json() を返すことで、JavaScript側で扱いやすいデータ形式(JSON)にする
  • isDone を切り替えることで完了/未完を反転させる

🧾 Step 4:View(Index.cshtml)で非同期ボタンを実装

Views/Todos/Index.cshtml を以下のように変更します👇

@model IEnumerable<MyFirstAspNetApp.Models.Todo>

<h2 class="mb-3">Todo一覧</h2>

<table class="table table-striped table-bordered">
    <thead class="table-dark">
        <tr>
            <th>ID</th>
            <th>タイトル</th>
            <th>状態</th>
            <th>操作</th>
        </tr>
    </thead>
    <tbody>
    @foreach (var item in Model)
    {
        <tr data-id="@item.Id">
            <td>@item.Id</td>
            <td>@item.Title</td>
            <td class="status">@((item.IsDone) ? "完了" : "未完了")</td>
            <td>
                <button class="btn btn-sm btn-success toggle-btn">
                    @(item.IsDone ? "戻す" : "完了")
                </button>
            </td>
        </tr>
    }
    </tbody>
</table>

@section Scripts {
<script>
document.querySelectorAll('.toggle-btn').forEach(btn => {
    btn.addEventListener('click', async e => {
        const row = e.target.closest('tr');
        const id = row.dataset.id;

        const res = await fetch('/Todos/ToggleDone', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
            },
            body: 'id=' + id
        });

        const data = await res.json();
        if (data.success) {
            const statusCell = row.querySelector('.status');
            statusCell.textContent = data.isDone ? '完了' : '未完了';
            e.target.textContent = data.isDone ? '戻す' : '完了';
        }
    });
});
</script>
}

💡 JavaScriptのポイント

コード 意味
fetch('/Todos/ToggleDone', { method: 'POST', ... }) Controllerに非同期POST送信
await res.json() Controllerの返り値(JSON)を受け取る
statusCell.textContent = ... ページを再読み込みせずに文字を更新

▶ Step 5:実行してみよう!

  1. /Todos を開く
  2. 「完了」ボタンを押す
  3. 即座に「完了」表示に変わる!
  4. 再度押すと「未完了」に戻る

🎉 ページの再読み込みなしでDBの内容を更新できました!

✅ まとめ

学び 内容
fetch() 非同期通信でサーバーとやり取り
ControllerのJson() JSに返しやすいデータ形式
ページの動的更新 DOM操作で部分書き換え
UX向上 ユーザー体験を大幅に改善

💬 学んでみて感じたこと

  • ControllerとJavaScriptを連携させるとアプリが一気に「動く」ようになる
  • ASP.NET MVCはサーバーサイド中心でもJSを簡単に統合できる
  • fetch()の書き方を覚えれば、API連携の基礎も理解できる
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?