【问题标题】:SilverStripe - limiting the number of many relations a dataobject can haveSilverStripe - 限制数据对象可以拥有的许多关系的数量
【发布时间】:2013-10-01 02:05:36
【问题描述】:

如果我想在 cms 中使用 GridField 管理 $has_many 关系,我将如何限制一个对象可以拥有的关系数量?这可能吗?

我可以在模型中执行此操作,还是必须将其添加到我用来添加和删除关系的GridField 中?

我正在考虑实现GridField_SaveHandler 来制作自定义GridFieldComponent,但不确定如果我检测到有问题如何使用它来中止保存。

【问题讨论】:

  • 您能不能只使用$this->MyRelationName()->Count() 来检查已经存在的数量,如果达到限制,只需从GridFieldConfig 中的GridFieldConfig 中删除GridFieldAddNewButton 吗@?您还可以在 onBeforeWrite() 钩子中添加额外的检查......
  • 是的,我刚刚尝试过,唯一的问题是,如果我添加第九个对象,页面不会重新加载操作,按钮仍然出现但无法正常工作,然后当我刷新页面并删除第 9 项按钮仍然隐藏,直到页面刷新
  • 您好,您有解决方法吗?我和你一样被困在这里。删除关系不会强制浏览器重新加载,因此在您刷新页面之前不会出现隐藏的“添加新”按钮。
  • 最后,我使用count() 的关系来触发添加GridFieldAddExistingAutocompleter 组件,只有在没有达到限制的情况下,如上所述,副作用也如上所述。我在想你可能会添加一些js来显示/隐藏通过这个检查隐藏的元素,我从来没有把它做到这一点,因为对我来说这是一个相当小的限制。如果您想出更好的解决方案,请在此处发布,因为我想看到它:)
  • 哦,我没有注意到你已经修复了它,现在才看到那个评论,我的回答基本上就是你已经用代码示例所做的。

标签: silverstripe


【解决方案1】:

以下 2 个解决方案不是解决这个问题的最干净的方法,而是最实用和最容易实施的方法。

基本上,我建议做的就是对对象进行计数,并在计数超过一定数量后取消添加新记录的能力。

如果您想限制单个关系/网格上的记录数(假设每个团队最多 5 名玩家):

class Player extends Dataobject {
    private static $db = array('Title' => 'Varchar');
    private static $has_one = array('TeamPage' => 'TeamPage');
}
class TeamPage extends Page {
    private static $has_one = array('Players' => 'Player');
    public function getCMSFields() {
        $fields = parent::getCMSFields();
        $config = GridFieldConfig_RecordEditor::create();
        if ($this->Players()->count > 5) {
            // remove the buttons if we don't want to allow more records to be added/created
            $config->removeComponentsByType('GridFieldAddNewButton');
            $config->removeComponentsByType('GridFieldAddExistingAutocompleter');
        }
        $grid = GridField::create('Players', 'Players on this Team', $this->Players(), $config);
        $fields->addFieldToTab('Root.Main', $grid);
        return $fields;
    }
}

如果你想在全局范围内限制记录总数(如果我们将这种方式限制为 5,这意味着如果 1 支球队已经有 3 名球员,那么第 2 支球队只能有 2 名球员):

class Player extends Dataobject {
    private static $db = array('Title' => 'Varchar');
    private static $has_one = array('TeamPage' => 'TeamPage');
    public function canCreate($member = null) {
        if (Player::get()->count() > 5) {
           return false;
        }
        return parent::canCreate($member);
    }
}
class TeamPage extends Page {
    private static $has_one = array('Players' => 'Player');
    public function getCMSFields() {
        $fields = parent::getCMSFields();
        $config = GridFieldConfig_RecordEditor::create();
        $grid = GridField::create('Players', 'Players on this Team', $this->Players(), $config);
        $fields->addFieldToTab('Root.Main', $grid);
        return $fields;
    }
}

【讨论】:

  • 是的,这就是我的网站的外观(第一个),尽管这并不完美,但我会接受它,因为我认为这是最接近我所追求的东西...除了javascript和ajax之外,有没有办法做这个检查?所以检查是一个ajax调用,如果需要,js可以隐藏元素......
【解决方案2】:

我写了一个快速的 jQuery 插件来限制 GridField 可以拥有的项目数量:-

在此处下载插件:-gridfieldlimit.js

https://letscrate.com/f/monkeyben/silverstripe/gridfieldlimit.js

在getCMSFields函数中设置插件:-

// Pass GridField configs, each one containing field name and item limit
$vars = array(
    "GridFieldLimits" => "[['GRIDFIELD_NAME_1', 3], ['GRIDFIELD_NAME_2', 6]]",
);

// Load the jquery gridfield plugin
Requirements::javascriptTemplate("themes/YOUR_THEME_NAME/javascript/gridfieldlimit.js", $vars);

【讨论】:

    【解决方案3】:

    对我有用:让 GridField 管理的 DataObject 的 canCreate 方法检查现有对象。

    当然,这不允许您实现自定义 GridFieldComponent,因为您需要修改 DataObject 代码。

    【讨论】:

    • 这是用于创建关系,而不是实际创建对象
    猜你喜欢
    • 1970-01-01
    • 2015-07-07
    • 2021-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-19
    相关资源
    最近更新 更多