Bootstrap Accordion在MVC&C#中一次性加载所有分组及组项
Hey there! I’ve got you covered on getting your Bootstrap Accordion to load all groups and their associated items in one go instead of just the selected group. Let’s break this down step by step:
First, you need your backend to return all main groups, each with its own array of child items — this way, the frontend gets the full dataset in one request. Here’s an example of what the JSON response should look like:
[ { "groupId": "marketing-team", "groupTitle": "营销分组", "items": [ "品牌推广计划", "社交媒体运营", "线下活动策划" ] }, { "groupId": "dev-team", "groupTitle": "开发分组", "items": [ "前端功能迭代", "后端接口优化", "数据库维护" ] } ]
Create an empty container in your HTML where all dynamic groups will be inserted:
<div class="accordion" id="fullGroupAccordion"> <!-- Dynamic groups will render here --> </div>
Use plain JS to loop through the full dataset and generate each Accordion group + its items. The key here is ensuring unique IDs for each collapse panel to avoid conflicts:
// Fetch full group data from your backend (use fetch/axios as needed) const groupsData = await fetch('/api/all-groups').then(res => res.json()); const accordionContainer = document.getElementById('fullGroupAccordion'); // Loop through each group to build HTML groupsData.forEach(group => { // Generate HTML for the group's items (customize this structure to your needs) const itemsHtml = group.items.map(item => `<li class="mb-1">${item}</li>`).join(''); // Build the full Accordion item const accordionItem = ` <div class="accordion-item"> <h2 class="accordion-header" id="heading-${group.groupId}"> <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapse-${group.groupId}" aria-expanded="false" aria-controls="collapse-${group.groupId}"> ${group.groupTitle} </button> </h2> <div id="collapse-${group.groupId}" class="accordion-collapse collapse" aria-labelledby="heading-${group.groupId}" data-bs-parent="#fullGroupAccordion"> <div class="accordion-body"> <ul class="list-unstyled">${itemsHtml}</ul> </div> </div> </div> `; // Insert the generated item into the container accordionContainer.innerHTML += accordionItem; });
If you’re using a frontend framework, the approach is similar but uses native looping syntax:
Vue Example
<template> <div class="accordion" id="fullGroupAccordion"> <div class="accordion-item" v-for="group in groupsData" :key="group.groupId"> <h2 class="accordion-header" :id="`heading-${group.groupId}`"> <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" :data-bs-target="`#collapse-${group.groupId}`" aria-expanded="false" :aria-controls="`collapse-${group.groupId}`"> {{ group.groupTitle }} </button> </h2> <div :id="`collapse-${group.groupId}`" class="accordion-collapse collapse" :aria-labelledby="`heading-${group.groupId}`" data-bs-parent="#fullGroupAccordion"> <div class="accordion-body"> <ul class="list-unstyled"> <li v-for="item in group.items" :key="item" class="mb-1">{{ item }}</li> </ul> </div> </div> </div> </div> </template> <script setup> import { ref, onMounted } from 'vue'; import axios from 'axios'; const groupsData = ref([]); onMounted(async () => { const res = await axios.get('/api/all-groups'); groupsData.value = res.data; }); </script>
React Example
import { useEffect, useState } from 'react'; import axios from 'axios'; function FullGroupAccordion() { const [groupsData, setGroupsData] = useState([]); useEffect(() => { const fetchGroups = async () => { const res = await axios.get('/api/all-groups'); setGroupsData(res.data); }; fetchGroups(); }, []); return ( <div className="accordion" id="fullGroupAccordion"> {groupsData.map(group => ( <div className="accordion-item" key={group.groupId}> <h2 className="accordion-header" id={`heading-${group.groupId}`}> <button className="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target={`#collapse-${group.groupId}`} aria-expanded="false" aria-controls={`collapse-${group.groupId}`}> {group.groupTitle} </button> </h2> <div id={`collapse-${group.groupId}`} className="accordion-collapse collapse" aria-labelledby={`heading-${group.groupId}`} data-bs-parent="#fullGroupAccordion"> <div className="accordion-body"> <ul className="list-unstyled"> {group.items.map(item => ( <li key={item} className="mb-1">{item}</li> ))} </ul> </div> </div> </div> ))} </div> ); } export default FullGroupAccordion;
- Unique IDs: Always use unique identifiers for each collapse panel (like
groupIdin the examples) — this prevents Bootstrap from mixing up collapse targets. - Mutual Exclusion: If you want multiple groups to stay open at the same time, remove the
data-bs-parentattribute from each collapse div. - Data Structure: The core fix is ensuring your backend returns a nested dataset of all groups + their items, not just a single group’s data.
内容的提问来源于stack exchange,提问作者user3782230

