Llamar a funciones JavaScript desde DotVVM con JS Directive
Tags: dotnet, javascript, html, webdev
Published: 2021-11-22 15:40:48

¡Hola! Un gusto saludarte. Para aprender a llamar funciones JavaScript desde DotVVM en ASP.NET, y viceversa, en este artículo tutorial aprenderemos a utilizar JS Directive al solicitar dos números desde una página web, realizar la operación en JavaScript, y mostrar los resultados en dicha página. 

###**¿Qué es JS Directive?**

La directiva JS es un conjunto de características que ofrece una manera de interactuar entre los controles de DotVVM y el código JavaScript. Por ejemplo, con JS Directive podemos llamar funciones JavaScript desde DotVVM, y enviar datos desde JavaScript hacia DotVVM. 

***Nota:*** Esta funcionalidad fue incorporada en DotVVM 3.0. 

###**Pasos a seguir**

Para que nosotros podamos establecer una comunicación entre DotVVM y JavaScript, estos son los pasos que debemos seguir: 

+ Declarar un modulo JavaScript con sus respectivas funciones. 
+ Registrar ese modulo en DotVVM Startup. 
+ Importar el modulo declarado en nuestras vistas DotVVM. 
+ ¡Manos a la obra! Llamar funciones JavaScript desde DotVVM, o recibir datos. 

###**Caso practico**

Para ver el funcionamiento de JS Directive en un ejemplo, sigamos los pasos antes mencionados para solicitar dos números al usuario, llamar una función de JavaScript que realice esa operación, y finalmente mostrar el resultado en la página web. 

Nuestro ejemplo se visualizaría de la siguiente manera: 

![Web app example to add two numbers.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b3do5370hwupvttq5c14.png)

Lo primero que debemos tener es el modulo JavaScript con sus funciones correspondientes, en este caso tenemos un archivo llamado `JavaScript.js` ubicado en el `wwwroot` con las siguientes definiciones:

```js
export default (contextApp) => new App(contextApp);
var WEB;

class App {

    constructor(contextApp) {
        this.contextApp = contextApp;
        WEB = contextApp;
    }

    operation(a, b) {
        let result = a + b;
        WEB.namedCommands["ResultOperation"](result);
    }

}
```

Aquí la función `operation` será la encargada de realizar la suma para luego poner el resultado en la sección `ResultOperation` definida en una vista con DotVVVM.

Con esta clase `App`, y su contexto definido, ahora podemos registrarlo en DotVVM para poder realizar llamadas desde DotVVM hacia JavaScript, y viceversa. En este sentido, debemos dirigirnos a la clase `DotVVM Startup`, y en el método `ConfigureResources` hacer referencia al archivo JavaScript en cuestión, y ponerle un nombre a este registro (en este caso el nombre será module):

```csharp
private void ConfigureResources(DotvvmConfiguration config, string applicationPath)
{

    //JS Directive
    config.Resources.Register("module", new ScriptModuleResource(new UrlResourceLocation("~/JavaScript.js"))
    {
        //Dependencies = new[] { "external/other-js-file" }
    });
}
```

Con esta definición, ya podemos utilizar JS Directive. Para la suma de los dos números, definiremos tres variables en el ViewModel (en este caso en el `DefaultViewModel.cs`): 

```csharp
public class DefaultViewModel : MasterPageViewModel
{
	public int Number1 { get; set;}
	public int Number2 { get; set;}
	public int Result { get; set;}
}
```

Finalmente, tendremos la sección de la vista ubicada en `Default.dothtml` de la siguiente manera:

```html
@viewModel JSDirective.ViewModels.DefaultViewModel, JSDirective
@masterPage Views/MasterPage.dotmaster
@js module

<dot:Content ContentPlaceHolderID="MainContent">
    <div class="content">
        <div class="content__text">
            <h1>JS Directive Demo</h1>
            <h3>Add two numbers</h3>

            <ul class="content-page">
                <li><b>Number1: </b></li>
                <li><dot:TextBox Text="{value: Number1}" Type="Number" /></li>
                <li><b>Number2: </b></li>
                <li><dot:TextBox Text="{value: Number2}" Type="Number" /></li>
            </ul>

            <dot:Button Text="Calculate"
                        Click="{staticCommand:_js.Invoke("operation", Number1, Number2);}" />

            <dot:NamedCommand Name="ResultOperation" Command="{staticCommand: (int id) => _root.Result = id}" />
            <h3>Result: <b>{{value: Result}}</b></h3>
        </div>
    </div>
</dot:Content>
```

En la vista, es necesario hacer referencia al modulo JavaScript que queremos utilizar, en este caso podemos referenciarlo con el identificador `js`, con el nombre del modulo registrado previamente: 

```js
@js module
```

Luego, en esta vista podemos mencionar tres cosas importantes:

+ Para establecer los dos números a sumar, se han utilizado dos controles de DotVVM de tipo `TextBox`. 
+ Para llamar a la función JavaScript podemos hacerlo con un `Button`, especificando el nombre de la función, y enviando los parámetros respectivos (`Number1`, y `Number2`).
+ El control `NamedCommand` nos permite invocar comandos desde JavaScript, en este caso se ha definido una sección con el nombre ResultOperation, para enviar el valor de la operación desde JavaScript y guardarlo en la variable `Result` (definida en el ViewModel desde DotVVM). 

Ccon este proceso, hemos podido llamar funciones JavaScript desde DotVVM, y enviar valores desde JavaScript hacia DotVVM. 

La documentación completa de JS Directive se puede revisar desde la documentación en DotVVM: [JS directive overview](https://www.dotvvm.com/docs/3.0/pages/concepts/client-side-development/js-directive/overview
).

###**Gracias por leer**###

Muchas gracias por leer, espero que este artículo te haya parecido interesante y pueda serte de utilidad en el futuro. 

El código fuente de este ejemplo lo puedes encontrar en el siguiente repositorio en GitHub: [DotVVM JS Directive](https://github.com/esdanielgomez/DotVVMJSDirective).

Si tienes alguna pregunta o alguna idea que necesites discutir, será un gusto poder colaborarte y juntos intercambiar conocimientos entre sí.

¡Nos vemos en [Twitter](https://twitter.com/esDanielGomez)! :)