5

I just want somehow to say "I want all methods in this project use [JavaScript]" Manually annotation every method is annoying

ais
  • 2,514
  • 2
  • 17
  • 24
  • No, but also it shouldn't be that way - server-side methods must not be annotated with `[]` (because they use functionality which is not available on client-side). – Ramon Snir Apr 09 '13 at 09:38
  • I also find code flooded with [] really annoying. This is one of the reasons why I decided to use Typescript instead. One possible solution could be to mark the whole module or class as JavaScript. Or is that not possible? – Oldrich Svec Apr 09 '13 at 12:15
  • It's possible, check out my answer for an example. – Taha Apr 09 '13 at 17:09

3 Answers3

6

F# 3 lets you mark a module with the ReflectedDefinition attribute (aka [JavaScript] in WebSharper) which marks all the methods underneath.

See More About F# 3.0 Language Features:

(Speaking of uncommon attributes, in F# 3.0, the [< ReflectedDefinition >] attribute can now be placed on modules and type definitions, as a shorthand way to apply it to each individual member of the module/type.)

Phillip Trelford
  • 6,513
  • 25
  • 40
  • 1
    For an example, you can check out my recent FunScript samples (I think the same code structure will work in WebSharper too): https://github.com/tpetricek/Documents/blob/master/Talks%202013/Love%20The%20Data%20(Channel9)/code/WorldBank.Web/Page.fs – Tomas Petricek Apr 09 '13 at 12:42
3

I think Phil's answer is the way to go - when you can mark an entire module or type, it does not add too much noise and it also allows you to distinguish between server-side and client-side code in WebSharper.

Just for the record, the F# compiler is open-source and so someone (who finds this issue important) could easily create branch that would add an additional command line attribute to override the setting. I think this is just a matter of adding the parameter and then setting the default value of the reflect flag in check.fs (here is the source on GitHub).

At the moment, the main F# repository does not accept contributions that add new features (see the discussion here), but it is certainly a good way to send a feature request to the F# team :-)

Tomas Petricek
  • 240,744
  • 19
  • 378
  • 553
2

If you annotate all your code with the JavaScript attribute, the WebSharper compiler will try to translate everything to JavaScript. A rule of thumb in WebSharper development is to separate server-side and client-side code, so you can simply annotate the module/class containing client-side code instead of every function/member if you're targeting .NET 4.5.

namespace Website

open IntelliFactory.WebSharper

module HelloWorld =

    module private Server =

        [<Rpc>]
        let main() = async { return "World" }

    [<JavaScript>] // or [<ReflectedDefinition>]
    module Client =

        open IntelliFactory.WebSharper.Html

        let sayHello() =
            async {
                let! world = Server.main()
                JavaScript.Alert <| "Hello " + world
            }

        let btn =
            Button [Text "Click Me"]
            |>! OnClick (fun _ _ ->
                async {
                    do! sayHello()
                } |> Async.Start)

        let main() = Div [btn]

    type Control() =

        inherit Web.Control()

        [<JavaScript>]
        override __.Body = Client.main() :> _
Taha
  • 443
  • 2
  • 5
  • I use websharper only for javascript replacement, so I don't really care about server side, anyway module annotation is much better then method. – ais Apr 09 '13 at 17:13