Pergunta

I'm a reasonably Java-savvy coder getting into Play2 framework.

I'm defining a little template and I thought it looked nice to use "options" as a way of passing in named parameters to a template.

So in my template (say, picker.scala.html) I'm taking these parameters

@(field: Field, label: String, options: Seq[(String, String)])

And on the page where I'm using it I am doing

@picker(myForm("shoesize"), "Your Shoe Size", options("color" -> "black"))

Question: how do do I deal with the options in the "picker" template? Can I do something like options.get("color")?

"RTFM" is a perfectly valid answer if it includes a pointer to the relevant documentation...

Edit: I figured out I can do @options.get(0)._2 etc. Am I missing the point of using options? Is there some better way of passing in a map of named parameters rather than a sequence of string, string pairs?

Solved

Thanks to the responses below, here's what I ended up doing:

My "picker" template now has this signature:

@(field: Field, 
  label: String, 
  options: Seq[(String, String)]=scala.collection.immutable.List())

That is, the options parameter defaults to an empty list, so the options are... well, optional.

In the picker template I then look for a "clearable" option like this:

@if(options.toMap.get("clearable").getOrElse("false")=="true"){
    clearable is true
} else {
    clearable is not true
}

So when I call the picker, I can just do

@picker(myForm("myField"), "Some Label")

or

@picker(myForm("myField"), "Some Label", options("clearable" -> "true))

I'm not sure this helps anybody, or if there's a better way of doing it, but it was just what I wanted and it works.

Foi útil?

Solução

If you need access to values from keys, it would be easier to use a Map[String, String] instead of a Seq[(String, String)].

In your code, it would look like :

@(field: Field, label: String, options: Map[String, String])

@picker(myForm("shoesize"), "Your Shoe Size", Map("color" -> "black"))

Then you can access to values using :

@options("color")

or iterate over the map :

@for((key, value) <- options) {
  @key - @value
}

Note that you can convert a Seq[(String, String)] to a Map[String, String] using the toMap method (ex: optionsSeq.toMap)

Outras dicas

Seq is not the thing you want in this case. You are really looking for a Map.

@(field: Field, label: String, options: Map[String, String])

Let's say you passed a Map("color" -> "black") into the picker thing. So then you may write something like that:

val color = options.get("color") //returns an Option[String]
color match {
  case Some(value) => System.out.println(value)
  case None => System.out.println("no value")
}

Or you may even write like that:

val color = options.getOrElse("color", "default color")

The reason it doesnt work with Seq[(String, String)] is because a (String, String) is a tuple which roughly looks like this:

class Tuple2[A, B](_1: A, _2: B)

So you are just making a sequence of objects. A Seq is a List-like structure compared to Java. In Java you cannot get an item from a List by passing it an item id, right? :)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top