核心思想
DedeCMS 本身不直接提供“开箱即用”的 AJAX 分类信息功能,我们需要手动实现它,核心思路分为三步:

(图片来源网络,侵删)
-
前端 (HTML/JS):
- 创建一个包含分类选择框(如下拉菜单)和内容展示区域的 HTML 页面。
- 监听分类选择框的变化事件(如
onchange)。 - 当事件触发时,获取当前选中的分类 ID。
- 使用 JavaScript 的
fetch或XMLHttpRequest(AJAX) 技术,将分类 ID 发送到一个专门的后端处理页面。
-
后端 (PHP):
- 创建一个专门用于接收 AJAX 请求的 PHP 文件(
ajax_info.php)。 - 在该文件中,接收前端传来的分类 ID。
- 根据这个 ID,使用 DedeCMS 的数据库查询函数(如
GetSonIds获取子分类 ID,GetOne获取单条信息,dsql执行复杂查询)来获取该分类下的所有信息列表。 - 将查询到的数据转换成 JSON 格式。
- 创建一个专门用于接收 AJAX 请求的 PHP 文件(
-
回调处理:
- 前端 JavaScript 接收到后端返回的 JSON 数据。
- 解析 JSON 数据,并动态地、用 JavaScript 生成 HTML 代码。
- 将生成的 HTML 代码插入到页面的内容展示区域。
详细实现步骤
假设我们要实现一个“城市”分类,选择不同的城市,动态加载该城市下的“租房”信息。

(图片来源网络,侵删)
第 1 步:准备数据和环境
-
创建分类信息模型: 在 DedeCMS 后台,
核心->内容模型管理->添加新模型,创建一个“租房”模型,这个模型需要有字段,标题、租金、面积、地址、联系人等。 -
创建分类栏目: 在
频道->分类信息,创建一个顶级栏目,租房信息”,然后为其创建子栏目,如“北京”、“上海”、“广州”等,确保每个子栏目都有对应的 ID。 -
添加测试数据: 往这些子栏目里添加几条测试的租房信息。
第 2 步:创建前端模板文件
在你的模板目录(如 /templets/default/)下创建一个新文件,ajax_list.htm。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">DedeCMS AJAX 分类信息列表</title>
<style>
body { font-family: Arial, sans-serif; }
#category-selector { margin-bottom: 20px; padding: 5px; }
#info-list { border: 1px solid #ccc; padding: 10px; }
.info-item { padding: 10px; border-bottom: 1px solid #eee; }
.info-item:last-child { border-bottom: none; }
.loading { color: #999; font-style: italic; }
</style>
</head>
<body>
<h1>租房信息列表</h1>
<!-- 1. 分类选择框 -->
<select id="category-selector">
<option value="0">请选择城市</option>
{dede:channel type='son' typeid='1' current=''}
<option value="{dede:field.id/}">{dede:field.typename/}</option>
{/dede:channel}
</select>
<!-- 2. 信息展示区域 -->
<div id="info-list">
<p class="loading">请选择一个城市以查看信息...</p>
</div>
<!-- 引入 jQuery 可以简化 AJAX 操作 (可选,但推荐) -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(document).ready(function(){
// 监听选择框的变化
$('#category-selector').on('change', function(){
var categoryId = $(this).val(); // 获取选中的分类ID
if(categoryId == 0){
// 如果选择的是“请选择”,则清空列表
$('#info-list').html('<p class="loading">请选择一个城市以查看信息...</p>');
return;
}
// 显示加载中提示
$('#info-list').html('<p class="loading">正在加载...</p>');
// 3. 发起 AJAX 请求
$.ajax({
url: '/plus/ajax_info.php', // 后端处理脚本的路径
type: 'GET',
data: { 'catid': categoryId }, // 将分类ID作为参数传递
dataType: 'json', // 期望服务器返回JSON数据
success: function(response){
// 4. 成功回调,处理返回的数据
if(response.status == 'success'){
var html = '';
if(response.data.length > 0){
$.each(response.data, function(index, item){
html += '<div class="info-item">';
html += '<h3><a href="' + item.arcurl + '">' + item.title + '</a></h3>';
html += '<p>租金:' + item.money + '元/月 | 面积:' + item.area + '㎡</p>';
html += '<p>地址:' + item.address + '</p>';
html += '</div>';
});
} else {
html = '<p>该分类下暂无信息。</p>';
}
$('#info-list').html(html);
} else {
$('#info-list').html('<p>加载失败:' + response.message + '</p>');
}
},
error: function(xhr, status, error){
// 请求失败处理
$('#info-list').html('<p>网络错误,请稍后重试。</p>');
console.error('AJAX Error:', error);
}
});
});
});
</script>
</body>
</html>
代码解释:
{dede:channel type='son' typeid='1' current=''}: 这句是 DedeCMS 的标签,用于获取 ID 为1的栏目的所有子栏目(即“北京”、“上海”等),并生成<option>。$('#category-selector').on('change', ...): 使用 jQuery 监听select元素的change事件。$.ajax({...}): 发起 AJAX 请求。url: 指向我们将要创建的后端文件。data: { 'catid': categoryId }: 将分类 ID 作为catid参数传递给ajax_info.php。dataType: 'json': 告诉 jQuery 我们期望服务器返回 JSON 格式的数据,它会自动解析。success: 请求成功后的回调函数,response就是服务器返回的 JSON 数据。
第 3 步:创建后端处理脚本
在你的 DedeCMS 根目录的 plus 文件夹下,创建一个新文件 ajax_info.php。
<?php
require_once(dirname(__FILE__)."/../include/common.inc.php");
// 1. 接收前端传来的参数
$catid = isset($catid) && is_numeric($catid) ? intval($catid) : 0;
// 定义返回给前端的数据结构
$return_data = array(
'status' => 'error',
'message' => '未知错误',
'data' => array()
);
// 2. 如果分类ID有效,则进行查询
if ($catid > 0) {
// 获取当前分类及其所有子分类的ID
// GetSonIds 是 DedeCMS 的一个函数,用于获取一个分类及其所有子分类的ID,用逗号连接
// 这很重要,因为信息可能发布在子分类里
$ids = GetSonIds($catid);
if ($ids) {
// 设置SQL查询
// 从 dede_archives (主表) 和 dede_addon17 (你的租房模型附加表,17是模型ID,需要改成你自己的) 中查询
// 请务必将 `17` 替换为你自己创建的“租房”模型的ID!
$sql = "SELECT a.id, a.title, a.typeid, a.pubdate,
t.money, t.area, t.address, t.contact
FROM dede_archives AS a
LEFT JOIN dede_addon17 AS t ON a.id = aid
WHERE a.arctypeid IN ({$ids}) AND a.arcrank > -1
ORDER BY a.id DESC LIMIT 10"; // 限制只返回10条
$dsql->SetQuery($sql);
$dsql->Execute('info_list');
$items = array();
while ($row = $dsql->GetArray('info_list')) {
// 获取文章的URL
$row['arcurl'] = GetOneArchive($row['id']);
$items[] = $row;
}
if (count($items) > 0) {
$return_data['status'] = 'success';
$return_data['message'] = '获取成功';
$return_data['data'] = $items;
} else {
$return_data['status'] = 'success';
$return_data['message'] = '该分类下暂无信息';
}
} else {
$return_data['message'] = '未找到相关分类';
}
} else {
$return_data['message'] = '请提供有效的分类ID';
}
// 3. 输出JSON数据并终止脚本
// header('Content-Type: application/json; charset=utf-8'); // 确保头部设置正确,现代浏览器通常能自动识别
echo json_encode($return_data, JSON_UNESCAPED_UNICODE);
// 安全终止,防止后续代码干扰输出
exit();
?>
代码解释:
require_once(...):引入 DedeCMS 的核心文件,这是必须的,否则无法使用 DedeCMS 的函数和数据库连接。GetSonIds($catid):关键函数,它会获取$catid及其所有子分类的 ID,并以逗号分隔的字符串形式返回(5,6,7),这确保了我们能查询到所有子分类下的信息。dsql:这是 DedeCMS 的全局数据库操作对象。dede_addon17:这是最容易出错的地方!17是你在第1步创建的“租房”模型的 ID,你需要在 DedeCMS 后台的内容模型管理中查看你的模型对应的 ID,并替换掉这里的17。json_encode(...):将 PHP 数组转换成 JSON 字符串输出给前端。exit():在输出 JSON 后立即终止脚本,避免页面其他内容被输出,导致 JSON 解析失败。
总结与注意事项
- 安全性:
intval($catid)对接收到的 ID 进行了类型转换和检查,防止 SQL 注入,但更安全的做法是使用预处理语句,但对于 DedeCMS 的dsql对象,直接使用intval是通用且有效的做法。 - 模型 ID:务必确认你的附加表名称(
dede_addon_x)中的x是正确的。 - URL 获取:
GetOneArchive($id)是 DedeCMS 官方推荐的获取文章链接的方法,它会自动处理静态、动态等多种URL规则。 - 性能:如果分类下的信息非常多,
LIMIT语句是必要的,避免一次性加载过多数据导致页面卡顿。 - 无 jQuery 版本:如果你不想使用 jQuery,可以用原生的
XMLHttpRequest或fetchAPI 来实现 AJAX 请求,原理是一样的,只是代码写法不同。 - 调试:如果前端收到的数据不正确,可以:
- 在浏览器开发者工具的 "Network" (网络) 面板中检查
ajax_info.php请求的响应内容,看是否是正确的 JSON。 - 在
ajax_info.php中使用var_dump($return_data); die();来打印 PHP 数组,检查数据逻辑是否正确。
- 在浏览器开发者工具的 "Network" (网络) 面板中检查
通过以上步骤,你就成功地为 DedeCMS 的分类信息频道添加了 AJAX 动态加载功能,用户体验会得到显著提升。
