在循环内访问控制器函数(ChildrenOf)

时间:2016-05-24 14:24:33

标签: silverstripe

我有一个页面类型(ProducerReport),其作用类似于摘要页面 - 它从各个页面(Shows)获取数据,并在每个页面上列出所有文章的主要信息。

使用ChildrenOf()让它变得非常简单和简单,我认为SilverStripe会为我做所有的工作我所要做的就是结构和风格吧!

然后悲剧发生了......

Shows我有一个由$ has_many链接的DataObject,它允许用户为每篇文章添加关键人物,如联系人等,这是通过GridField(ShowsContacts)完成的。

起初我有点假设只需添加必要的变量即可获得ShowContacts的数据 - 这不起作用。

然后在视图中我在黑暗中拍摄并尝试使用实际工作的$ID并返回帖子的ID。

所以我继续将这个添加到ProducerReport控制器中,我希望能完成这项任务,允许我执行查询以获取相关联系人并在ChildrenOf循环内循环它

但是,控制器在循环中不执行任何操作。它输出任何东西的唯一时间是我把循环外部。

ProducerReport.php

class ProducerReport_Controller extends Page_Controller {

    # Get the Show Contacts for the Show, based on ShowsID
    public function something($SiteID){

        # Needs to be cast to int as param comes in as string
        $x = (int)$SiteID;
        var_dump(ShowsContact::get()->find('ShowID', $x)->Role);

    }
}

ProducerReport.ss

<div class="producer-report">

<% loop ChildrenOf(current-shows).sort('PercentageComplete', 'DESC') %>

    <div class="show">

        <div class="banner">
        <% if $ReportImage %>
            $ReportImage
        <% else %>
            <img src="/assets/_placeholders/producer_report_cover.png" />
        <% end_if %>

            <a href="$Link" title="View $Title Show Page"><h2>$Title <span>($ProjectCode)</span></h2></a>

        </div><!-- . banner -->

        <a class="hub-link" target="_blank" href="http://website.com?job=$ProjectCode">Hub</a><!-- . hub-link -->

        <div class="stats">

            <h3>Show Statistics</h3>

            <dl>
                <dt>Client</dt>
                <% if $Client %>
                    <dd>$Client</dd>
                <% else %>
                    <dd>None set</dd>
                <% end_if %>
            </dl>

            <dl>
                <dt>Percentage Complete</dt>
                <% if $PercentageComplete %>
                    <dd>$PercentageComplete%</dd>
                <% else %>
                    <dd>-</dd>
                <% end_if %>

            </dl>

        </div><!-- . stats -->

    </div><!-- . show -->

    <!-- Here I need to retrieve info of the contacts belonging to the page -->

    <!-- Inside the ChildrenOf loop, this DOESNT output anything -->
    $something($ID)

<% end_loop %>

    <!-- This outside the loop DOES output a job role -->
    $something(84)

</div><!-- . producer report -->

编辑 - 附加代码

这是ProducerReport获取数据的内容,此模型的所有直接数据都出现在ChildrenOf循环中; ShowsContact数据无法访问,如果我尝试使用$something($ID)功能进行查询,则在循环内使用时无效。

Shows.php

class Shows extends Page {

    private static $db = array(
        'ProjectCode' => 'Varchar(4)',
        'Client' => 'Varchar(255)',
        'PercentageComplete' => 'Int'
    );

    private static $has_one = array(
        'ReportImage' => 'Image'
    );

    private static $has_many = array(
        'ShowsContacts' => 'ShowsContact'
    );

    public function getCMSFields(){

        # GridField / Show Contacts
        $conf = GridFieldConfig_RelationEditor::create();

        $gridField = new GridField('ShowsContact',
                                   'Show Contact List',
                                   $this->ShowsContacts(), $conf);

        $fields->addFieldsToTab('Root.Content.ShowContact', array(
            $gridField
        ));

        return $fields;

    }
}

class Shows_Controller extends Page_Controller {

    # Get key people from ShowsContact class // input via ShowsContact GridField

    # THIS HERE is the data that I need displayed on ProducerReport

    public function getKeyPeople(){

        if($this->ShowsContacts()->exists()){

            $result = new ArrayList();

            foreach($this->ShowsContacts()->column('MemberID') as $teamMemberID){

                $member = Member::get()->byID($teamMemberID);

                $result->add(new ArrayData(array(
                    'PictureURL' => $member->ImageURL,
                    'Role' => $this->ShowsContacts()->find('MemberID', $teamMemberID)->Role,
                    'Firstname' => $member->FirstName,
                    'Surname' => $member->Surname,
                    'Nickname' => $member->Nickname,
                    'Email' => $member->Email,
                    'Ext' => $member->Extension,
                    'Site' => Site::get()->byID($member->SiteID)->Title
                    )
                ));
            }

            return $result;
        }
        else
            return null;
    }
}

我的问题是 - 如果我无法在循环中执行循环,或者我做错了什么,我将如何从其他页面类型获取数据以及通过关系链接到它的数据?

3 个答案:

答案 0 :(得分:1)

<击> AHHHH !! omfg !!!! 好的,所以在这个问题上拍摄了许多许多后,我发现了如何使这个工作。

解决方法是在循环内使用$ Top。[Method]。我认为它是因为SilverStripe在循环中做了它自己的事情,无论出于何种原因变得有点盲目。根据我的理解 - 你必须告诉方法走出循环以便它看到/使用控制器

ProducerReport.ss中的上述代码中删除并将其修改为与问题相关...

<% loop ChildrenOf(current-shows).sort('PercentageComplete', 'DESC') %>
...
    $Top.something($ID) <!-- works perfectly, ID is passed. Output is as expected!
...

# Or when in a loop it'll be like so...

    <% loop $Top.something($ID) %>
        # ArrayList / ArrayData output...
    <% end_loop %>

<% end_loop %>

我无法相信这花了我很长时间才找到解决方案! 任何陷入类似这样或类似事情的人都可以找到答案,因为我老实说即将放弃并重写此页面类型的所有内容,并使用查询将所有数据放入模板...... < / p>

编辑/注意 :我发现如果您有一个名为getUserName的方法(例如),则无法省略'get '与$Top一起使用时...因此在模板中,您需要在使用时$Top.getUserName放置

答案 1 :(得分:0)

如果你认为你已经解决了问题,不确定它是否相关,但是something控制器方法(甚至是使用过的?)将永远不会转储你认为的任何DataObject::get()或{ {1}} ORM调用始终返回DataList::create()的实例,而非个人DataList

如果您正在尝试查看该查询中SS的内容,请尝试使用DataObject代替,正如您可能猜到的那样,返回第一个->first()(或DataObject子类)你的清单:

DataObject

答案 2 :(得分:-1)

对于您的模板,您可以这样做:

ProducerReport.ss

<% loop Shows %>
    <% loop ShowsContacts %>
        <%-- contact details here --%>
    <% end_loop %>
<% end_loop %>

Where&#39; ShowsContacts&#39;是从节目到联系人的关系的名称