Reputation: 433
The Scala.js documentation has a nice example on how to implement a jQuery facade which also supports chaining:
@js.native
trait JQueryGreenify extends JQuery {
def greenify(): this.type = ???
}
object JQueryGreenify {
implicit def jq2greenify(jq: JQuery): JQueryGreenify =
jq.asInstanceOf[JQueryGreenify]
}
However as far as I understood it, this example assumes that the greenify
plugin has been implemented in Javascript already. E.g. like
$.fn.greenify = function() {
this.css( "color", "green" );
return this;
}
How would this plugin be implemented in Scala.js?
Upvotes: 2
Views: 339
Reputation: 22085
There two ways to define a "jQuery plugin" in Scala.js. The first one is a safe and idiomatic Scala-esque way, but is only for consumption by other Scala.js code. The second is a bit ugly, but it can be used by JavaScript code.
In Scala, and in Scala.js, the patch-the-prototype thing that actual jQuery plugins do is discouraged. Instead, we use implicit classes:
implicit class JQueryGreenify(val self: JQuery) extends AnyVal {
def greenify(): self.type = {
self.css("color", "green")
self
}
}
And then you can simply do
jQuery("#some-element").greenify()
when you have JQueryGreenify
in scope (as an import, typically).
This method does not pollute the actual prototype of jQuery objects. It is a pure-Scala abstraction. It is clean and safe, but that means it cannot be used by JavaScript code.
If you need to call greenify
from JavaScript, you actually need to add a function property on the jQuery.fn
object. Since the function needs to use the this
parameter, we have to explicitly ascribe it to a js.ThisFunction
(see also Access the JS this from scala.js):
js.Dynamic.global.jQuery.fn.greenify = { (self: JQuery) =>
self.css("color", "green")
self
}: js.ThisFunction
which is basically a transliteration of the original JavaScript code from the question.
Upvotes: 3