An open API service indexing awesome lists of open source software.

https://github.com/yoshiki-okawa/blazorjsproxy

Dynamic proxy of Microsoft.JSInterop.IJSRuntime which makes defining and invoking JS object much easier
https://github.com/yoshiki-okawa/blazorjsproxy

blazor blazor-wasm blazor-webassembly dispatchproxy jsinterop jsruntime net50 proxy

Last synced: 6 months ago
JSON representation

Dynamic proxy of Microsoft.JSInterop.IJSRuntime which makes defining and invoking JS object much easier

Awesome Lists containing this project

README

          

# BlazorJSProxy
Dynamic proxy of Microsoft.JSInterop.IJSRuntime which makes defining and invoking JS object much easier.\
All you need is to define interface for JavaScript class with matching properties and methods.\
[![NuGet](https://img.shields.io/nuget/v/BlazorJSProxy.svg)](https://www.nuget.org/packages/BlazorJSProxy/)\
\
See the actual working examples in Class1.cs in ClassLibrary1 project.\
**Example 1 - Existing window variable**
```c#
[JSTarget(ConstructorFunction = "MouseEvent")]
public interface IMouseEvent : IAsyncDisposable
{
ValueTask OffsetX { get; set; }
ValueTask OffsetY { get; set; }
}

[JSTarget(GlobalVariable = "window.location")]
public interface ILocation : IAsyncDisposable
{
ValueTask Href { get; set; }
}

// Use JSTarget with GlobalVariable as window is a global variable in JS.
[JSTarget(GlobalVariable = "window")]
public interface IWindow : IAsyncDisposable
{
ValueTask Location { get; set; }
// Use JSName to use custom propery name instead.
[JSName("onclick")]
Func OnClick { get; set; }
// Use JSName to use custom propery name instead.
[JSName("ondblclick")]
Action OnDoubleClick { set; }
}

private async Task TestWindow()
{
// Create a JS proxy of window.
await using var window = await BlazorJSProxy.CreateAsync(jsRuntime, null);
// Get current URL.
var location = await window.Location;
Console.WriteLine(await location.Href); // https://localhost:5001/counter
// Register a callback function to onclick with Func.
window.OnClick = async evt =>
{
Console.WriteLine("Clicked:" + await evt.OffsetX + "," + await evt.OffsetY); //Clicked:99,18
await Task.CompletedTask;
};
// Register a callback function to ondblclick with Action.
window.OnDoubleClick = async evt =>
{
Console.WriteLine("Double clicked:" + await evt.OffsetX + "," + await evt.OffsetY); //Double clicked:99,18
};
// window object is disposed automatically with await using from both .NET and JS.
}
```

**Example 2 - Custom classes**
```c#
// Use JSTarget with ConstructorFunction as Parent is a custom class defined.
[JSTarget(ConstructorFunction = "Parent")]
public interface IParent : IAsyncDisposable
{
ValueTask Name { get; set; }
ValueTask GetChild();
// IArray is a simple Array JS proxy so that no parsing from JS and .NET vice versa are required until absolutely needed.
ValueTask> GetChildren();
ValueTask Child { get; set; }
// IArray is a simple Array JS proxy so that no parsing from JS and .NET vice versa are required until absolutely needed.
ValueTask> Children { get; set; }
}
[JSTarget(ConstructorFunction = "Child")]
public interface IChild : IAsyncDisposable
{
ValueTask Name { get; set; }
}

private async Task TestCustomParentChildClasses()
{
await DefineCustomParentChildClasses();
await TestProxyReturnType(x => x.GetChild(), x => x.GetChildren());
await TestProxyReturnType(x => x.Child, x => x.Children);
}

private async Task DefineCustomParentChildClasses()
{
await jsRuntime.InvokeVoidAsync("eval", @"
window.Parent = class Parent {
name = 'Parent';
child = this.getChild();
children = this.getChildren();

getChild() {
return new Child('Child1');
}

getChildren() {
return [new Child('Child1'), new Child('Child2')];
}
};
window.Child = class Child {
constructor(name)
{
this.name = name;
}
};");
}

private async Task TestProxyReturnType(Func> getChild, Func>> getChildren)
{
// Create a JS proxy of Parent. Every time this is called, new instance of Parent is created in JS.
await using var parent = await BlazorJSProxy.CreateAsync(jsRuntime, null);
// Get the parent name.
Console.WriteLine(await parent.Name); // Parent
// Get a child.
await using var child1 = await getChild(parent);
// Get the child name.
Console.WriteLine(await child1.Name); // Child1
// Set the child name to Child3
child1.Name = new ValueTask("Child3");
// Get the child's Name again.
Console.WriteLine(await child1.Name); // Child3
// Get children.
await using var children = await getChildren(parent);
// Get a number of children.
Console.WriteLine(await children.Length); // 2
// Get the first child name.
Console.WriteLine(await (await children[0]).Name); // Child1
// Get the second child name.
Console.WriteLine(await (await children[1]).Name); // Child2
// Set the first child name to Child4
(await children[0]).Name = new ValueTask("Child4");
// Get the first child name again.
Console.WriteLine(await (await children[0]).Name); // Child4
// Set the first child = the second child.
children[0] = new ValueTask(await children[1]);
// Get the first child name again.
Console.WriteLine(await (await children[0]).Name); // Child2
// Get the second child name again.
Console.WriteLine(await (await children[1]).Name); // Child2
}
```