如何在外观中创建可选 "options"?

How do I create optional "options" in a facade?

我正在尝试为 bootstrap 弹出函数创建一个外观,它最多可以接受 11 个可选参数。在我的 scalajs 代码中,我只想传递我需要从库维护的合理默认值覆盖的参数,即:PopoverOptions(animation = false) 就像我在 javascript 中所做的那样。这似乎是制作外观的推荐方法,但它使所有必需的参数成为可能:

trait PopoverOptions extends js.Object {
  val animation: String = js.native
  val container: String = js.native
  val content: String = js.native
  ... 
}

object PopoverOptions {
  def apply(animation: String, container: String, content: String, ...): PopoverOptions = {
    js.Dynamic.literal(animation=animation, container= container, content = content, ...).asInstanceOf[PopoverOptions ]
  }
}

看起来一种方法是为每个可能的参数排列定义一个应用程序,但是当有很多覆盖参数时,这会变得过快:

def apply(animation: String): ...
def apply(container: String): ... 
def apply(animation: String, container: String): ...
...

创建具有许多覆盖参数的选项参数外观的惯用方法是什么,这些覆盖参数通常具有合理的库维护默认值?

注意:两个答案都有 pros/cons 因此决定在不离开 SO 的情况下查看两种方式可能会有所帮助所以这里是 JSOptionBuilder 方法的摘要:

import org.querki.jquery.JQuery
import org.querki.jsext._

@js.native
trait PopoverOptions extends js.Object
object PopoverOptions extends PopoverOptionBuilder(noOpts)
class PopoverOptionBuilder(val dict:OptMap) extends JSOptionBuilder[PopoverOptions, PopoverOptionBuilder](new PopoverOptionBuilder(_))
{
  def animation(v:String) = jsOpt("animation", v)
  def container(v:String) = jsOpt("container", v)
  def content(v:String) = jsOpt("content", v)
  ...
}

使用:PopoverOptions.animation("yay").container("container").content("bottom")._result

您可以使用 Scala 的默认参数值,结合 js.UndefOr 元素类型,如下所示:

object PopoverOptions {
  @inline
  def apply(
      animation: js.UndefOr[String] = js.undefined,
      container: js.UndefOr[String] = js.undefined,
      content: js.UndefOr[String] = js.undefined,
      ...): PopoverOptions = {
    val result = js.Dynamic.literal()
    animation.foreach(result.animation = _)
    container.foreach(result.container = _)
    content.foreach(result.content = _)
    ...
    result.asInstanceOf[PopoverOptions]
  }
}

那你就可以用PopoverOptions(animation = false)打电话了

定义站点有点冗长,但它会完成工作。

另一种方法是使用为此目的创建的 JSOptionBuilder。 (我写了很多 jQuery 门面,他们 总是 有这个问题。)JSOptionBuilder 不像以前那么重要(这是在“ |" 运算符被引入),但我仍然发现它通常是处理复杂外观的最佳方式。

这是the full description of this approach。 (请注意,这非常详细 - 前半部分是关键内容,其余部分处理所有 somewhat-common 边缘情况。)