web-dev-qa-db-ja.com

Twig継承オブジェクトのinstanceof

私はpropelから次の機能を使用しています http://www.propelorm.org/documentation/09-inheritance.html

Symfony2とTwigも使用しています

上記の機能を使用したクラス構造は次のようになります

class Event {}

class Birthday extends Event {}

class Walking extends Event {}

ここで、イベントオブジェクトをtwigテンプレートに渡し、それがどのタイプのイベントであるかを知りたいです。

たとえば、誕生日の場合はケーキの画像を表示し、ウォーキングイベントの場合は地図のルートを表示したいとします。

この機能が存在しないため、instanceofをTwigで使用できません。なぜこれが存在しないのか誰かがいますか?そして、次のようなことをしなくてもこの機能を複製できる方法はありますか?

 public function getType()

各クラスで、または

 public function isBirthday()

イベントクラスで。

私はこれをgithubで見つけましたが、私には役に立ちません。私は彼らにコメントして、私が答えを得ることができるかどうかを確認しました。

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

18

instanceofはテンプレートに表示されるべきものではないという意見を共有します。この場合、小枝テストを使用します

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 %}
51
KingCrunch

これを実現する間接的な方法は、継承された各オブジェクトに一意のメソッドがあることがわかっている場合、オブジェクトのメソッドをテストすることです。おそらく、BirthdayクラスにはgetBirthday()があり、WalkingクラスにはgetMap()がありますか?

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

テンプレートでinstanceofを使用することは、アーキテクチャの観点からは嫌われています。 「必要」な位置にいる場合は、アーキテクチャの問題を発見した可能性があります。あなたの場合のgetTypeソリューションはおそらく最高です。それでも、それをイベント基本クラスに入れて、実装クラスの名前を読み取ることができます。

4

別の解決策:

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

その後、から継承するすべてのクラスで動作します

class Birthday extends Event {}

class Walking extends Event {}

次に、twig:

{{ 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 %}
1
Nico

私も同様の問題を抱えていました。それはホテルソフトウェアの継承に関連していました。基本クラス「RoomEquipment」と、「Bed」、「ElectricAppliances」の継承がありました。

class BaseRoomEquipment {}

class Bed extends BaseRoomEquipment {}

class ElectricAppliances extends BaseRoomEquipment {}

そしてもちろん、RoomEquipmentに対してOneToManyの関係を持つクラス「Room」。

テンプレートでは、ベッドのみをレンダリングしたかったのですが、部屋はベッドや電化製品などの基本設備と関係があります。

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>

プロパティアクセサーコンポーネントのおかげで-これは可能です。これで、twigはインスタンスの種類を確認する必要がなくなり、確認する必要もありません。

0
Nikola Svitlica

ユーザーが定義したエンティティと、'addToListing'としてマークされたフィールドのみを一覧表示するindex.html.twigを作成しようとしています。そのため、何がわからないのかわかりません。印刷しています。

{% 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')またはより良い解決策。

私にとってクリーンな解決策について何かアドバイスはありますか?

0
juanmf