【问题标题】:Silverstripe Multiple Userforms on one page一页上的 Silverstripe 多个用户表单
【发布时间】:2016-04-25 14:07:39
【问题描述】:

我正在尝试创建一个页面,该页面将在选项卡式视图中显示多个用户窗体。例如基本联系表、索取报价表等。

我想我可以创建一个新的页面类型并循环遍历子项以显示表单,但是 $Form 变量没有呈现表单。

<% loop $Children %>
   <div>
     <h2>$Title</h2>
     $Form
   </div>
<% end_loop %>

我在这里遗漏了什么,还是有其他方法可以使用模板文件中的 ID 呈现表单?

【问题讨论】:

  • 您在该上下文中迭代 DataObjects,而不是控制器类及其方法。让它工作也有点棘手:stackoverflow.com/questions/30404467/…
  • 根据表单及其“功能”,在循环中为它们添加占位符并使用 js 将占位符替换为扩展为表单内容大小的 iframe 可能会更“容易” .

标签: silverstripe


【解决方案1】:

您可以尝试以下方法。

在您的页面持有者控制器中创建一个函数以从特定子项(必须是 UserDefinedForm 页面)获取表单。为此,您需要创建此子页面的控制器。

public function ChildForm($pageID) {
  $page = UserDefinedForm::get()->byID($pageID);
  $controller = UserDefinedForm_Controller::create($page);
  return $controller->Form();
}

之后,您将在循环中调用此函数并将当前子 ID 传递给它

<% loop $Children %>
   <div>
     <h2>$Title</h2>
     $Top.ChildForm($ID)
   </div>
<% end_loop %>

这应该(代码未经测试)返回您想要的表单。

【讨论】:

    【解决方案2】:

    这里的问题是DataObject/Page 和Controller 之间的区别。循环$Children 会返回一个DataObject,而Form 函数和模板变量是UserDefinedForm 控制器的一部分。

    另一个答案显示了一个可行的解决方案,但它有一些头发:

    • 将范围跳转到控制器以传递 ID 以获取表单
    • 其他数据库查询
    • 要求所有子页面的类型为UserDefinedForm

    我们可以实现一个更通用的解决方案,删除其中的一些元素并使您的代码更易于维护。

    将以下内容添加到Page 类(不是控制器)中:

    function getInLoopForm() {
        if (in_array('UserDefinedForm', $this->ClassAncestry)) {
            $controllerName = $this->ClassName . '_Controller';
            $controller = $controllerName::create($this);
            if ($controller->hasMethod('Form')) {
                return $controller->Form();
            }
        }
        return false;
    }
    

    第一部分检查当前对象的类祖先中是否有UserDefinedForm。如果是,我们然后创建适当的控制器并返回表单。

    您的模板代码将如下所示:

    <% loop $Children %>
       <div>
         <h2>$Title</h2>
         $InLoopForm
       </div>
    <% end_loop %>
    

    这个解决方案是通用的,原因有以下三个:

    • 在我们的getInLoopForm 函数中,值“UserDefinedForm”可以替换为任何扩展Page 的类。如果您愿意,甚至可以将其调到 YML 值。
    • 对于 SilverStripe,页面的控制器名称必须与“{PageClassName}_Controller”匹配,因此我们可以通过动态计算控制器名称来滥用它。这允许您扩展 UserDefinedForm 及其控制器,我们仍然可以调用正确的函数。
    • 您只需要DataObject 即可访问表单,不需要您自己的控制器。

    【讨论】:

    • 看起来是个不错的解决方案。当您必须使用命名空间时,这将如何在 Silverstripe 4 中工作?提前致谢。
    【解决方案3】:

    对于 SS 4,需要对代码进行少量更改:

    public function getInLoopForm() {
        if (in_array('SilverStripe\UserForms\Model\UserDefinedForm', $this->ClassAncestry)) {
            $controller = UserDefinedFormController::create($this);
            if ($controller->hasMethod('Form')) {
                return $controller->Form();
            }
        }
        return false;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-03
      • 1970-01-01
      • 2017-05-18
      • 1970-01-01
      相关资源
      最近更新 更多