20

我正在使用 propel http://www.propelorm.org/documentation/09-inheritance.html的以下功能。

我也在使用 Symfony2 和 Twig

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

class Event {}

class Birthday extends Event {}

class Walking extends Event {}

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

例如,如果是生日,我想显示蛋糕的图像,如果是步行事件,我想显示地图路线。

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

 public function getType()

在每个班级,或

 public function isBirthday()

在事件类中。

我在 github 上找到了这个,但它对我没有用。我已经对他们发表了评论,看看我是否能得到答案。

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

4

6 回答 6

55

我同意这个观点,这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 %}
于 2013-09-11T21:30:45.880 回答
6

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

{% if yourobject.methodName is defined %}
   //Stuff that should only output when the object in question has the requested method
{% endif %}
于 2013-05-29T10:51:20.507 回答
4

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

于 2012-04-12T10:01:02.847 回答
1

另一个解决方案:

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 ... }}

或者

{% if event.isInstanceOfBirthday %}
    ... do something for Birthday instance ...
{% else %}
    ... do something for Walking instance ...
{% endif %}
于 2017-01-16T15:19:22.797 回答
0

我有类似的问题,它与酒店软件中的继承有关。我有一个基类“RoomEquipment”,并继承了“Bed”、“ElectricAppliances”......

class BaseRoomEquipment {}

class Bed extends BaseRoomEquipment {}

class ElectricAppliances extends BaseRoomEquipment {}

当然,还有一个与 RoomEquipment 有 OneToMany 关系的“Room”类。

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

我没有在树枝模板中进行测试,而是在 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 组件 - 这是可能的。现在,您的树枝不必检查实例类型,也不必检查

于 2014-06-12T09:01:28.837 回答
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 :/ 所以对于这种情况,我需要 | date('format') 或一些更好的解决方案。

对我来说有什么清洁解决方案的建议吗?

于 2014-01-11T00:08:48.843 回答