Twig instanceof用于继承对象

时间:2012-04-11 20:28:43

标签: symfony propel twig single-table-inheritance

我使用了来自http://www.propelorm.org/documentation/09-inheritance.html的以下功能。

我也在使用Symfony2和Twig

我有一个使用上述功能的类结构,看起来像这样

class Event {}

class Birthday extends Event {}

class Walking extends Event {}

现在我将一个事件对象传递给一个twig模板,我想知道它是什么类型的事件

例如,我想在生日时显示一个蛋糕的图像,我想在步行事件中显示地图路线。

我无法在Twig中使用instanceof,因为此功能不存在。 有谁现在为什么这不存在? 有没有办法可以复制这个功能,而不必像

那样做
 public function getType()

在每个班级,或

 public function isBirthday()

在事件类中。

我在github上发现了这个但对我没用。我评论了他们,看看我是否能得到答案。

https://github.com/fabpot/Twig/issues/553

6 个答案:

答案 0 :(得分:51)

我同意这一观点,instanceof不应出现在模板中。我在这种情况下使用twig-tests

class MyTwigExtension extends TwigExtension
{
    public function getTests ()
    {
        return [
            new \Twig_SimpleTest('birthday', function (Event $event) { return $event instanceof Birthday; }),
            new \Twig_SimpleTest('walking', function (Event $event) { return $event instanceof Walking; })
        ];
    }
}

在模板中

{% if event is birthday %}{# do something #}{% endif %}

答案 1 :(得分:5)

如果您知道每个继承的对象都有一个唯一的方法,那么实现此方法的间接方法是测试方法的对象。也许你的Birthday类有一个getBirthday(),而你的Walking类有一个getMap()?

{% if yourobject.methodName is defined %}
   //Stuff that should only output when the object in question has the requested method
{% endif %}

答案 2 :(得分:4)

从架构的角度来看,在模板中使用instanceof是不受欢迎的。如果您发现自己处于“需要”的位置,那么您可能已经发现了架构中存在的问题。您的getType解决方案可能是最好的。您仍然可以将它放入事件基类中,并将其读出实现类的名称。

答案 3 :(得分:0)

我正在尝试制作一个index.html.twig,其中列出了用户定义的实体,并且只列出了标记为'addToListing'的字段。所以我到了“我不知道”的位置我知道我在打印什么。

{% for entity in entities %}
    <tr>
        {% for heading in headings %}
            <td><a href="{{ path('document_show', { 'id': entity.id, docType: metaData.className }) }}">{{ attribute(entity, heading) }}</a></td>
        {% endfor %}
    </tr>
{% endfor %}

标题碰巧是一个\ DateTime:/所以对于这种情况我需要|日期('格式')或更好的解决方案。

有关清洁解决方案的任何建议吗?

答案 4 :(得分:0)

我有类似的问题,它与酒店软件的继承有关。我有一个基地&#34; RoomEquipment&#34;和继承&#34; Bed&#34;,&#34; ElectricAppliances&#34; ....

class BaseRoomEquipment {}

class Bed extends BaseRoomEquipment {}

class ElectricAppliances extends BaseRoomEquipment {}

当然,还有一个班级&#34; Room&#34;关于OneToMany与RoomEquipment的关系。

在模板上,我只想要铺床,但是房间与基础设备有关,包括床和电器。

而不是在twig模板中测试,在Room类中我创建了一个方法getBeds,就是这样。

class Room {

  private $equipment;

  public getBeds() 
  {
     $res = [];
     foreach($this->getEquipment() as $eq) {
        if ($eq instanceof Bed) $res[] = $eq;
     }
     return $res;
  }

  // Rest of class here....

}

当然,在Twig:

<div>
    {% for Bed in Room.beds %}
       {{ Bed.nbPersons }}
    {% endfor %}
</div>

感谢Property Accessor组件 - 这是可能的。现在,您的树枝不必检查实例类型,也不必检查

答案 5 :(得分:0)

另一种解决方案:

class Event {
    ...
    public function isInstanceOfBirthday() {
        return $this instanceof Birthday;
    }
}

然后它将适用于任何继承自

的类
class Birthday extends Event {}

class Walking extends Event {}

然后在你的树枝上:

{{ event.isInstanceOfBirthday ? ... something for Birthday instance ... : ... something for Walking instance ... }}

OR

{% if event.isInstanceOfBirthday %}
    ... do something for Birthday instance ...
{% else %}
    ... do something for Walking instance ...
{% endif %}