Twig instanceof для объектов наследования
Я использую следующую функцию от propel http://www.propelorm.org/documentation/09-inheritance.html.
Я также использую Symfony2 и Twig
У меня есть структура класса, использующая вышеприведенную функцию, которая выглядит примерно так:
class Event {}
class Birthday extends Event {}
class Walking extends Event {}
теперь я передаю объект события в шаблон ветки, и я хочу знать, какой тип события он
Например, я хочу отображать изображение торта, если его день рождения, и я хочу отображать маршруты карты, если это событие для ходьбы.
Я не могу использовать instanceof в Twig, поскольку эта функция не существует.
Кто-нибудь теперь, почему этого не существует?
и есть ли способ реплицировать эту функциональность, не делая что-то вроде
public function getType()
в каждом классе, или
public function isBirthday()
в классе событий.
Я нашел это на github, но это бесполезно для меня. Я прокомментировал их, чтобы узнать, могу ли я получить ответ.
https://github.com/fabpot/Twig/issues/553
Ответы
Ответ 1
Я разделяю мнение, что instanceof
ничего не должно появляться в шаблоне. Я использую twig-тесты для этого случая
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 %}
Ответ 2
Косвенным способом достижения этого является тестирование объекта для метода, если вы знаете, что каждый унаследованный объект имеет уникальный метод. Возможно, у вашего класса Birthday есть getBirthday(), в то время как ваш класс Walking имеет getMap()?
{% if yourobject.methodName is defined %}
//Stuff that should only output when the object in question has the requested method
{% endif %}
Ответ 3
Использование instanceof в шаблоне неодобрительно с архитектурной точки зрения. Если вы окажетесь в положении, когда вам это нужно, вы, вероятно, обнаружили проблему в своей архитектуре. Ваше решение getType в вашем случае, вероятно, самое лучшее. Вы могли бы поместить это в базовый класс события и прочитать его название класса реализации.
Ответ 4
Я пытаюсь сделать 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:/So для такого случая мне нужно будет | дата ( "формат" ) или какое-то лучшее решение.
Какой-нибудь совет для чистого решения для меня?
Ответ 5
У меня была аналогичная проблема, она была связана с наследованием в программном обеспечении отеля. У меня был базовый класс "RoomEquipment", и наследование "Bed", "ElectricAppliances"....
class BaseRoomEquipment {}
class Bed extends BaseRoomEquipment {}
class ElectricAppliances extends BaseRoomEquipment {}
И, конечно, класс "Комната" с отношением OneToMany к RoomEquipment.
В шаблоне я хотел только создать кровати, но комната имеет отношение к базовому оборудованию, которое включает в себя кровати и электроприборы.
Вместо тестирования в шаблоне ветки, в классе Room я создал метод getBeds, и thats it.
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 - это возможно. Теперь вашей ветке не нужно проверять тип экземпляра, и он не делает
Ответ 6
Другое решение:
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 %}