SORU
9 Mart 2012, Cuma


Nasıl her yerde parametreleri play2 geçen önlemek için?

Play1, ben genellikle eylemleri tüm verileri almak, onları doğrudan görünümleri kullanın. Açıkça görünümünde parametreler ilan etmeye ihtiyacımız yok, çünkü bu çok kolaydır.

Ama play2, ben bulduğumuzu bildirmek için tüm parametreleri(dahil request) baş manzarası, olacak çok sıkıcı almak her veri hareketleri ve pas onları içine bakıldı.

Eğer ön sayfasında veritabanından yüklenen menüleri görüntülemek için ihtiyacım var, örneğin, main.scala.html bunu tanımlamak için var:

@(title: String, menus: Seq[Menu])(content: Html)    

<html><head><title>@title</title></head>
<body>
    <div>
    @for(menu<-menus) {
       <a href="#">@menu.name</a>
    }
    </div>
    @content
</body></html>

Sonra her alt sayfa ilan buldum

@(menus: Seq[Menu])

@main("SubPage", menus) {
   ...
}

Sonra menüler olsun ve her eylem görmek için bunu geçmek zorundayım:

def index = Action {
   val menus = Menu.findAll()
   Ok(views.html.index(menus))
}

def index2 = Action {
   val menus = Menu.findAll()
   Ok(views.html.index2(menus))
}

def index3 = Action {
   val menus = Menu.findAll()
   Ok(views.html.index(menus3))
}

Şu an için main.scala.html eğer çok varsa ne tek bir parametre var mı?

Yani sonunda, doğrudan görünümünde Menu.findAll() tüm karar verdim:

@(title: String)(content: Html)    

<html><head><title>@title</title></head>
<body>
    <div>
    @for(menu<-Menu.findAll()) {
       <a href="#">@menu.name</a>
    }
    </div>
    @content
</body></html>

Eğer iyi ya da tavsiye edilir bilmiyorum, bunun için daha iyi bir çözüm var mı?

CEVAP
9 Mart 2012, Cuma


Benim görüşüme göre, şablonlar statik olarak yazılan aslındaiyişey: şablon arıyorsanız derler eğer başarısız olmayacağını garanti ediyoruz.

Ancak gerçekte " arama sitelerinde biraz klişe ekler. Amabunu azaltabilirsiniz(statik yazarak avantajları kaybetmeden).

Bunu başarmak için iki yol görüyorum Scala: eylemler kompozisyon ya da örtük parametreleri kullanarak. Java yararlı değerleri saklamak ve açıkça şablonları parametre olarak geçmek zorunda kalmadan şablonlar onları almak için Http.Context.args harita kullanmanızı öneririm.

Kapalı parametreleri kullanarak

main.scala.html şablon parametreleri sonunda menus parametre yer olarak işaretle“”: . örtülü

@(title: String)(content: Html)(implicit menus: Seq[Menu])    

<html>
  <head><title>@title</title></head>
  <body>
    <div>
      @for(menu<-menus) {
        <a href="#">@menu.name</a>
      }
    </div>
    @content
  </body>
</html>

Şimdi Eğer şablonları arıyor bu ana şablon, sen-ebilmek var menus parametre örtülü olarak kabul etmiş ve sana main şablon ile Scala derleyicisi ise ilan olarak örtülü bir parametre olarak bu şablonlar olarak

@()(implicit menus: Seq[Menu])

@main("SubPage") {
  ...
}

Ama eğer tamamen geçti eğer kumanda örtülü bir değer, şablon dediğiniz yerden kapsamında mevcut olarak temin etmeniz gerekir. Örneğin, kontrol cihazını aşağıdaki yöntem bildirebilirsiniz:

implicit val menu: Seq[Menu] = Menu.findAll

Eylemleri sadece şunları yazmak mümkün olacak sonra

def index = Action {
  Ok(views.html.index())
}

def index2 = Action {
  Ok(views.html.index2())
}

this code sample 50 *ve bu yaklaşım hakkında daha fazla bilgi bulabilirsiniz.

GüncellemeGüzel bir blog yazısı bu modeli gösteren de here yazılmıştır.

Eylemleri kullanarak kompozisyon

Aslında, genellikle yararlı şablonları (örneğin this sample) RequestHeader değer vermek. Bu kolayca örtülü isteği bir değer alıyor: eylemler yazabilirsiniz çünkü teyp kodu için çok klişe eklemez

def index = Action { implicit request =>
  Ok(views.html.index()) // The `request` value is implicitly passed by the compiler
}

Şablonlar genellikle en azından bu örtülü parametre almak beri, daha zengin bir değer örneğin menüler içeren ile değiştirin. Oyun 2 actions composition mekanizmasını kullanarak yapabilirsin.

Context sınıf tanımlamak zorunda yapmak için, altta yatan bir istek kaydırma:

case class Context(menus: Seq[Menu], request: Request[AnyContent])
        extends WrappedRequest(request)

Sonra ActionWithMenu aşağıdaki yöntemi tanımlayabilirsiniz:

def ActionWithMenu(f: Context => Result) = {
  Action { request =>
    f(Context(Menu.findAll, request))
  }
}

Bu gibi kullanılabilir:

def index = ActionWithMenu { implicit context =>
  Ok(views.html.index())
}

Ve şablonlar ile örtülü bir parametre olarak içeriği alabilir. E. g. main.scala.html için:

@(title: String)(content: Html)(implicit context: Context)

<html><head><title>@title</title></head>
  <body>
    <div>
      @for(menu <- context.menus) {
        <a href="#">@menu.name</a>
      }
    </div>
    @content
  </body>
</html>

Kompozisyon tüm örtülü değerleri şablonları toplamak için izin verir eylemleri kullanarak tek bir değer gerektirir, ama diğer yandan bazı esnekliğini kaybeder

Http Kullanarak.İçerik (Java)

Beri Java yok Scala'nın implicits mekanizması veya benzeri, eğer sen de istersen önlemek için açıkça pass şablon parametreleri olası bir şekilde saklamak için onları Http.Context nesne hangi hayat sadece süresi bir istek. Bu nesne, 44* *tür args bir değer içerir.

Böylece, the documentation açıklandığı gibi bir avcı, yazarak başlayabilirsiniz:

public class Menus extends Action.Simple {

    public Result call(Http.Context ctx) throws Throwable {
        ctx.args.put("menus", Menu.find.all());
        return delegate.call(ctx);
    }

    public static List<Menu> current() {
        return (List<Menu>)Http.Context.current().args.get("menus");
    }
}

Statik yöntem, geçerli bağlam menüleri almak için sadece bir kısaltma. Sonra Menus eylem avcı ile karışık olması denetleyicisi açıklama:

@With(Menus.class)
public class Application extends Controller {
    // …
}

Son olarak, aşağıdaki gibi şablonlar menus değerini almak

@(title: String)(content: Html)
<html>
  <head><title>@title</title></head>
  <body>
    <div>
      @for(menu <- Menus.current()) {
        <a href="#">@menu.name</a>
      }
    </div>
    @content
  </body>
</html>

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • CMTelly

    CMTelly

    2 Mayıs 2007
  • TheOtherMau5

    TheOtherMau5

    6 Mart 2012
  • wwjoshdo

    wwjoshdo

    25 Mayıs 2009