2014-10-29 19 views
9

In JavaScript idiomatico è comune che una funzione accetti un "oggetto opzioni" come ultimo parametro. Questo è il posto in cui di solito si mettono tutti i parametri opzione/usati raramente, ad es.Come posso creare "oggetti opzioni" in Scala.Js?

jQuery.ajax({ 
    url: "http://www.example.com/foo", 
    success: function() { 
     .. 
    } 
}) 

La documentazione corrente per Scala.JS recommands utilizzando un tratto Scala per rappresentare le opzioni oggetto, ma che porta ad un problema quando si deve creare le opzioni dal momento che non è possibile passare una classe anonima in codice JavaScript.

Come possono essere creati tali oggetti di opzione dal codice Scala?

+0

possibile duplicato di [Qual è il modo suggerito per istanziare un js.Object per i wrapper API] (http://stackoverflow.com/questions/23663059/questo-è-il-suggerito-inviato-instantiare-a -js-object-for-api-wrappers) – gzm0

risposta

10

si consiglia il seguente (se si è scelto di creare facciate-tipi):

trait AjaxOptions extends js.Object { 
    val url: String = js.native 
    val success: js.Function0[Unit] = js.native 
} 

object AjaxOptions { 
    def apply(url: String, success: js.Function0[Unit]): AjaxOptions = { 
    js.Dynamic.literal(url = url, success = success).asInstanceOf[AjaxOptions] 
    } 
} 

Il vantaggio è che la trasmissione di tipo non sicuro è contenuta in una singola posizione. Inoltre, se si decide di aggiungere/rimuovere campi da/a AjaxOptions, si spera (si spera) di adattare anche il metodo apply dell'accompagnatore. Di conseguenza, il tier ti informerà su dove devi cambiare le tue invocazioni (piuttosto che avere il nuovo campo impostato su undefined).

Per ulteriori informazioni, consultare What is the suggested way to instantiate a js.Object for API wrappers.

2

Ecco un metodo che ho trovato a lavorare abbastanza bene:

val fooOptions = js.Dynamic.literal().asInstanceOf[FooOptions] 
fooOptions.url = ... 
fooOptions.bar = ... 
jsFunc(..., fooOptions) 

Naturalmente questo presuppone che il FooOptions caratteristica ha dichiarato i campi come var. In caso contrario, sarà necessario utilizzare

val fooOptions = js.Dynamic.literal(
    url = ..., 
    bar = ..., 
) 
jsFunc(..., fooOptions) 

ma che è meno sicuro sul tipo.

Se stai dichiarando le proprie opzioni tratto, si potrebbe anche aggiungere un oggetto associato con un appropriato applicare metodo:

trait FooOptions extends Js.Object { 
    var foo: js.String = ??? 
    var bar: js.String = ??? 
} 

object FooOptions { 
    def apply(): FooOptions = 
     js.Dynamic.literal().asInstanceOf[FooOptions] 
} 

Che farò chiamare il codice molto più bella:

val fooOptions = FooOptions() 
fooOptions.foo = ... 
fooOptions.bar = ... 
jsFunc(..., fooOptions) 
+0

Non consiglierei di farlo. Se aggiungerai mai un campo a "FooOptions", il typer non si lamenterà nelle posizioni in cui li crei. Pertanto, il campo sarà impostato su 'undefined', che è di tipo non corretto per la maggior parte dei tipi di campo. – gzm0

+0

Questo è un punto interessante, ma non sono sicuro di capire perché Scala.Js avrebbe effettivamente impostato i campi a cui non stai assegnando. Credo che dovrò fare un piccolo test per vedere come sono gli oggetti reali. –

+0

Quindi, ho appena fatto un piccolo test e sembra che il mio codice * faccia * la cosa giusta.L'oggetto delle opzioni risultante non * ha * proprietà che non vengono impostate esplicitamente dal lato Scala delle cose. Tuttavia, la tua versione ha il vantaggio che può funzionare usando "val" piuttosto che "var", quindi c'è quel potenziale compromesso. –

2

Questa domanda è piuttosto vecchio, ma dal momento che le persone sono ancora venendo qui:

Se si dispone di un ampio e complesso Opzioni oggetto (come è tipico, per esempio, le classi jQuery UI), si consiglia di costruire un facciata per quello che usa JSOptionBuilder, che si trova in the jsext library. JSOptionBuilder non è un vero toccasana, ma è un meccanismo non troppo importante per costruire e usare oggetti opzioni arbitrariamente complessi.

Problemi correlati