Call JS from DotVVM
The JS directive feature is new in DotVVM 3.0.
The JS directive functionality is not supported in Internet Explorer 11.
After the JS module is imported using the JS directive, you can export functions to be called from DotVVM using static commands.
Declare functions in module
To export a function, just declare it in the module class.
The function can take any number of arguments, and can return a value which may be used in DotVVM binding expression to modify the viewmodel.
export default context => new MyModule(context);
class MyModule {
...
sum(number1, number2) {
return number1 + number2;
}
}
// ---
// alternative declaration without using the class
export default context => {
...
return {
sum(number1, number2) {
return number1 + number2;
},
...
}
}
Call the function from DotVVM
Once you use the @js
directive in the markup file, you can use the _js
variable in binding expressions.
It provides a generic Invoke
method which can be used to invoke functions in modules:
_js.Invoke<TReturnValue>("functionName", arg1, arg2, ...)
If the function doesn't return anything, you can use just _js.Invoke("functionName", ...)
.
The sum
function declared above can be called like this:
<dot:TextBox Text="{value: Number1}" />
<dot:TextBox Text="{value: Number2}" />
<dot:Button Text="Calculate"
Click="{staticCommand: Result = _js.Invoke<double>("sum", Number1, Number2)}" />
DotVVM has no way to verify that the function exists, gets the correct arguments, and that it returns the value of the specified type. If the function call doesn't work, check out the Developer Tools (F11) console in your browser for more info.
From DotVVM 4.0, this function also checks whether the underlying JavaScript code doesn't return Promise. If it does,
InvokeAsync
must be used, orTReturnValue
must beTask
orTask<T>
. See the following section for information about async functions.
Async functions
If the function needs to perform an asynchronous action, you can return a Promise, and use _js.InvokeAsync<T>
function instead. It is just a syntax helper for calling _js.Invoke<Task<T>>
- the signature and usage is the same.
In order to retrieve the value, you need to access the Result
of the task.
class MyModule {
...
// this function returns a Promise
async getNumberOfAttendees() {
let response = await fetch("/api/attendees");
let attendees = await response.json();
return attendees.length;
}
}
<dot:Button Text="Refresh"
Click="{staticCommand: Count = _js.InvokeAsync<int>("getNumberOfAttendees").Result}" />