2

我有一个关于服务器端数据网格控件的design基本问题implementation(类似于 asp.net GridView)。

我已经创建了 dummyDataGrid.scala.html但我可以用更复杂和更实用(使用函数式编程)的方式编写。

    @(ID: String, List: Seq[model.admin.Partner.Partner], Columns: Seq[String])(content: Html= Html(""))
@import model.admin.Partner.Partner
<table>
    <thead>
        <tr>
        @for(j <- Columns) {
            <td>@j</td>
        }
        </tr>
    </thead>

    @for(i <- List) {
        <tr> @for(j <- Columns) {
            <td> @code.classes.EntityFactory.getValue[Partner](i, j)</td>
        }
        </tr>
    }
</table>

基本上我有一个用于表头的循环和第二个用于通过反射获取价值的双循环。

object EntityFactory {
  def getValue[T](entity: T,fieldName: String)(implicit ev: scala.reflect.ClassTag[T]) = {
    entity.getClass.getMethods.find(_.getName == fieldName).get.invoke(entity)
  }
}

在我看来,我像这样使用这个 Datagrid:

    @DataGrid(ID = "partners", List = Partners, Columns = Seq("ID","Name", "ShortName")){

                    }

我希望拥有的

我想要这样的东西:

@DataGrid(ID = "partners", List = Partners){
                        @LinkColumn(ID = "url", Propety = "ID",Url = controllers.admin.routes.PartnerController.read(""))
                        @LabelColumn(ID = "Name", Property="Name", CssClass="Some")
                        @LabelColumn(ID = "Email",Property="Email", CssClass="Some")
                        @DateDateColumn(ID = "ActiveFrom")
                    }

在这里,我为此创建了结构

在此处输入图像描述

在某些专栏中,我想做一些技巧来UrlProperty. 像这样的东西:

    @(ID: String,entity: Partner, Property: String, Url: String)
@import model.admin.Partner.Partner
    <div>
        here I want to inject code.classes.EntityFactory.getValue[Partner](entity,"ID")
        into @Url
    </div>
<a href="@Url(code.classes.EntityFactory.getValue[Partner](entity,Property))">klik</a>

感谢阅读和帮助。


编辑

一段时间后,我终于自己找到了答案。此代码分为两个区域:codeview

代码

以下是描述列类型的特征或类。

trait Column {
  val ID: String
  val Label: Option[String]
  val Header: String
  val Property: String
  val AlternateProperty: Option[String]
  val Visible: Boolean
  val Enabled: Boolean
}

object Column {}
case class LinkColumn(ID: String,
                      Label: Option[String] = None,
                      Header: String,
                      Property: String,
                      AlternateProperty: Option[String] = None,
                      Visible: Boolean = true,
                      Enabled: Boolean = true,
                      Url: Any => Call,
                      Type: String = LinkColumnType.Action
                       ) extends Column {}

case class LabelColumn(ID: String,
                       Label: Option[String] = None,
                       Header: String,
                       Property: String,
                       AlternateProperty: Option[String] = None,
                       Visible: Boolean = true,
                       Enabled: Boolean = true) extends Column {}

case class MergedActionColumn(ID: String,
                              Label: Option[String] = None,
                              Header: String,
                              Property: String,
                              AlternateProperty: Option[String] = None,
                              Visible: Boolean = true,
                              Enabled: Boolean = true,
                              Actions: Seq[LinkColumn]) extends Column {}
object LinkColumnType extends Enumeration {
  type Type = Value
  val Link = ""
  val Action = "btn btn-success"
}

还有一些助手代码。

object EntityFactory {
  def getField(entity: Any,fieldName: String) = {
    entity.getClass.getMethods.find(_.getName == fieldName).get.invoke(entity)
  }
}

意见

DataGrid.scala.html

@(ID: String, List: Seq[Any], CssClass: String = "",
        ShowCreateButton: Boolean = true)(Columns: Seq[Any])(implicit request: play.api.mvc.RequestHeader, lang: play.api.i18n.Lang)
@import code.classes.{EntityFactory => ef}
@import code.views.tags.DataGrid.{LabelColumn, LinkColumn, Column, MergedActionColumn}
@import views.html.tags.controls.DataGrid.{LabelColumn => vLabelColumn, LinkColumn => vLinkColumn}
@import code.views.tags.DataGrid.LinkColumnType
@import code.Ext

    @if(ShowCreateButton){
        <a class="btn btn-success" href="@controllers.admin.routes.PartnerController.create()">
            <i class="icon-zoom-in icon-white"></i>
            @Ext.te("common.add", lang.code)
        </a>
    }
<table class="@CssClass">
    <thead>
        <tr>
        @for(j <- Columns) {
            @j match {
                case s: MergedActionColumn =>{
                       <td>@s.Header</td>
                }
                case s: Column => {
                    <td>@s.Header</td>
                }
                case _ => {}
            }
        }
        </tr>
    </thead>
    @for(l <- List) {
        <tr>
        @for(c <- Columns) {
            @c match {
                case s: LabelColumn => {
                    @vLabelColumn(ID = s.ID, Header = s.Header, Property = s.Property,
                        Visible = s.Visible)(entity = l)
                }
                case s: LinkColumn => {
                    @vLinkColumn(ID = s.ID, Label = s.Label, Header = s.Header, Property = s.Property,
                        AlternateProperty = s.AlternateProperty, Visible = s.Visible, Enabled = s.Enabled,
                        Url = s.Url, Type = LinkColumnType.Link
                    )(entity = l)
                }

                case s: MergedActionColumn => {
                   <td> <table> <tr>
                    @for(s <- s.Actions) {
                        @vLinkColumn(ID = s.ID, Label = s.Label, Header = s.Header, Property = s.Property,
                            AlternateProperty = s.AlternateProperty, Visible = s.Visible, Enabled = s.Enabled,
                            Url = s.Url, Type = LinkColumnType.Action, CssClass = "no-border no-bg"
                        )(entity = l)
                    }
                    </tr>
                    </table>
                   </td>
                }
            }
        }
        </tr>
    }
    </table>

LinkColumn.scala.html

@(  ID: String,
    Label: Option[String] = None,
    Header: String,
    Property: String,
    AlternateProperty: Option[String] = None,
    Visible: Boolean = true,
    Enabled: Boolean = true,
    Url: String => Call,
    Type: String = code.views.tags.DataGrid.LinkColumnType.Action,
    CssClass: String = "")(implicit entity: Any)

    @import code.classes.{EntityFactory => ef}

    <td class="@CssClass">
        <a href="@Url(ef.getField(entity, Property).toString)" class="@Type">
            @Label.getOrElse(ef.getField(entity, AlternateProperty getOrElse Property).toString)
        </a>
    </td>

LabelColumn.scala.html

@(ID: String,
        Label: Option[String] = None,
        Header: String,
        Property: String,
        AlternateProperty: Option[String] = None,
        Visible: Boolean = true,
        Enabled: Boolean = true)(implicit entity: Any)
@import code.classes.{EntityFactory => ef}
<td>
    @ef.getField(entity, Property)
</td>

数据网格的使用:

@DataGrid(ID = "facilities", List = Facilities, CssClass = "table table-striped table-bordered bootstrap-datatable datatable",
                    ShowCreateButton = true)(
                    Seq(
                        LabelColumn(ID = "ID", Header = "ID", Property = "ID"),
                        LabelColumn(ID = "Name", Header = "Nazwa", Property = "Name"),
                        MergedActionColumn(ID = "Actions", Header = "Actions", Property = "ID", Actions = Seq(
                            LinkColumn(ID = "Update", Header = "ID", Property = "ID", Url = pfc.update, Label = Some("Update")),
                            LinkColumn(ID = "Delete", Header = "ID", Property = "ID", Url = pc.delete, Label = Some("Delete")),
                            LinkColumn(ID = "Delete", Header = "ID", Property = "ID", Url = pc.read, Label = Some("View")),
                            LinkColumn(ID = "Delete", Header = "ID", Property = "ID", Url = pfc.index, Label = Some("Facilities"))
                        ))
                    )
                )

当然,这只是基本的 scaldfolding,但它展示了如何使用 playframework 视图,如 asp.net 或 jsf 中的控件。

4

1 回答 1

0

您可能想要检查现有的表单助手以及(过时的)引导程序支持。查看html.scala播放源中的对应文件

这是在游戏中实现非平凡组件的好例子。

于 2013-07-25T15:33:23.613 回答