سؤال

أنا أستخدم Play Framework 2.1.5 في تطبيق Java.

لدي مكون عرض يأخذ قائمة بالكائنات العامة كمعلمة.في هذا المكون، أريد التكرار في القائمة والحصول على بعض خصائص كل عنصر.

سيبدو هذا مثل هذا:

@(elements: List[_])

@for((element, i) <- elements.view.zipWithIndex) {
    @i
    @element.id
    @element.name
}

(أحتاج إلى تلك القيم الثلاث)

ولكن بالتأكيد، element.id و element.name لن يتم تجميعها حتى لو كان نوع الكائنات التي أضعها في القائمة يحتوي على هذه الطرق.لذلك فعلت هذا:

@for((element, i) <- elements.view.zipWithIndex) {
    @defining(
        ViewsUtils.getGenericElementId(element),
        ViewsUtils.getGenericElementName(element)) {
            case (id, name, something) =>
                @i
                @id
                @name
        }
}

وفي فئة المرافق Java:

public final class ViewsUtils {

    public static String getGenericElementId(Object object) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        return object.getClass().getMethod("getId").invoke(object).toString();
    }

    public static String getGenericElementName(Object object) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        return object.getClass().getMethod("getName").invoke(object).toString();
    }
}

يعمل هذا ولكني أعلم أنه ليس صحيحًا لأنه قد يؤدي إلى RuntimeException في حالة عدم وجود إحدى هذه الطرق لنوع الكائن الذي أضعه في القائمة.

وهنا افتراضاتي:

  1. صب العناصر

  2. استخدام الميراث

  3. نظرًا لأنني أحتاج فقط إلى خاصيتين لكل كائن (المعرف والاسم)، يمكنني استخدام الخريطة، لكني بحاجة إلى فهرس الحلقة (هل من الممكن الحصول عليه من الخريطة؟) ولن يعمل إذا احتجت لذلك أكثر من 2 خصائص.

  4. ربما يوفر Scala بناء الجملة لهذا النوع من الأشياء.

أو ربما أنا فقط أبحث في الاتجاه الخاطئ.

شكرا لك على مساعدتك.

هل كانت مفيدة؟

المحلول

حسنًا، هذا كثير جدًا بالنسبة للتعليق، لذا سأخاطر بنشره كإجابة.

على افتراض أنك ترغب في عدم الحصول على RuntimeException لقد ذكرت أنه من المنطقي أن يقوم كائنك بتنفيذ واجهة ما (أو مزج السمات، كما يقال في Scala)، لذلك لن تخاطر بالحصول على استثناء ولن تحتاج بعد الآن إلى التفكير للحصول على القيم.

لنفترض أنك تعلن عن هذه السمة:

trait GenericObject {
  val id: Long
  val name: String
}

ثم تعلن بعض فئات الحالة:

case class A(id: Long, name: String, someOtherField: SomeType) extends GenericObject {
  //your implementation
}

case class B(id: Long, name: String) extends GenericObject

case class C(id: Long, name: String) extends B(id, name)

الآن يمكنك تغيير القالب الخاص بك مثل هذا:

@(elements: List[GenericObject])

@for((element, i) <- elements.view.zipWithIndex) {
  @i
  @element.id
  @element.name
}

ويجب عليك اجتياز قائمة GenericObjectإلى القالب الخاص بك:

val myObjects: List[GenericObject] = List(A(1, "A name"), B(2, "B name"), C(3, "C name"))
Ok(your_template.scala.html(myObjects))
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top