You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Silverstripe 4中如何向模板传递多组数组并正确遍历

在Silverstripe 4中传递多个ArrayList到模板的问题

嘿,我来帮你捋清楚这个问题:你想在模板里用两个循环展示不同的列表数据,思路方向是对的,但合并ArrayList的方式犯了个小错误,导致模板里无法正确访问到数据。

先说说你当前代码的问题

你把$SSArrayList和$JSBrandsArray直接push到了新的$mainArray(一个ArrayList)里,这意味着$mainArray里的两个元素就是这两个列表本身,但它们没有对应的键名。当你在模板里<% loop $MainArray %>时,每一次循环的上下文都是其中一个列表(第一次是$SSArrayList,第二次是$JSBrandsArray),这时候你在这个上下文里写<% loop $SSArrayList %>,模板根本找不到名为$SSArrayList的变量——因为当前上下文就是这个列表本身,自然渲染不出来。

虽然var_dump()能看到完整数据,但Silverstripe模板的上下文机制和普通PHP数组访问是不一样的,这就是问题所在。

给你两种可行的解决方案

方案一:直接传递两个独立变量(推荐,更简单直观)

不需要合并成一个ArrayList,直接把两个列表作为独立参数传给模板就行:

控制器代码:

// 先创建好你的$SSArrayList
$sqlQuery = new SQLSelect();
$sqlQuery->setFrom('Wine');
$sqlQuery->addWhere($queryArray);
$results = $sqlQuery->execute();
$SSArrayList = new ArrayList;
foreach($results as $result) {
    $SSArrayList->push(new ArrayData($result));
}

// 重新创建$JSBrandsArray(用ArrayData包装更规范)
$JSBrandsArray = new ArrayList;
foreach($results as $result) {
    if (!empty($result['BrandName'])) {
        $JSBrandsArray->push(new ArrayData([
            'Brandname' => $result['BrandName']
        ]));
    }
}

// 直接传递两个变量到模板
return $this->customise([
    'WineResults' => $SSArrayList,
    'BrandList' => $JSBrandsArray
])->renderWith("Layout/WinesList");

模板代码(WinesList.ss):

<!-- 遍历酒品数据 -->
<% loop $WineResults %>
    <p>酒品品牌:$BrandName,其他字段:$YourOtherField</p>
<% end_loop %>

<!-- 遍历品牌列表 -->
<% loop $BrandList %>
    <p>品牌:$Brandname</p>
<% end_loop %>

方案二:用ArrayData作为容器传递(如果需要统一管理)

如果你一定要用一个变量把两个列表传进去,别用ArrayList(它是用来存同类型列表项的),改用ArrayData——它是Silverstripe用来存键值对数据的容器:

控制器代码:

// 先创建好两个ArrayList(同上)

// 用ArrayData包装两个列表
$mainData = new ArrayData([
    'SSArrayList' => $SSArrayList,
    'JSBrandsArray' => $JSBrandsArray
]);

// 传递这个包装后的变量
return $this->customise(['MainData' => $mainData])->renderWith("Layout/WinesList");

模板代码:

<!-- 直接通过容器访问两个列表,不需要外层loop -->
<% loop $MainData.SSArrayList %>
    <p>酒品信息:$BrandName</p>
<% end_loop %>

<% loop $MainData.JSBrandsArray %>
    <p>品牌:$Brandname</p>
<% end_loop %>

额外小提示

创建$JSBrandsArray时,最好用ArrayData包装每个元素,虽然普通数组在模板里也能访问,但用Silverstripe的标准数据对象更符合框架的设计规范,避免潜在的上下文访问问题。

内容的提问来源于stack exchange,提问作者mckinselberg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:32:24