【问题标题】:Blazor JSInvokable without static function没有静态函数的 Blazor JSInvokable
【发布时间】:2022-11-07 21:26:54
【问题描述】:

我的 Blazor 组件带有一些 JavaScript 代码。当 JavaScript 代码检测到点击时,我想在 Blazor 组件中调用 JSInvokable 函数来更新 UI。

所以,我创建了一个这样的函数

[JSInvokable]
public static async Task ChangeTab(string val)
{
    Console.WriteLine(val);
}

JavaScript 中,我添加了以下行:

DotNet.invokeMethodAsync('myComponent', 'ChangeTab', tabText);

此代码正在运行,函数ChangeTab 接收到我期望的值。问题是这个函数是static。所以,我不能改变变量。我试图改变这样的代码(激活页面是组件中的一个函数)

[JSInvokable("ChangeTab")]
public async Task ChangeTab(string val)
{
    ActivatePage(val);
}

但在这种情况下,我收到一个错误,因为该函数不是静态的。

错误:System.ArgumentException:程序集“PSC.Blazor.Components.ScrollTabs”不包含具有 [JSInvokableAttribute("ChangeTab")] 的公共可调用方法

我检查了Microsoft documentation,但我不明白如何将JSInvokable 函数更改为不是static

【问题讨论】:

    标签: javascript blazor blazor-webassembly blazor-component


    【解决方案1】:

    您可以执行以下操作:

    MyComponent.razor

    @code {
        DotNetObjectReference<MyComponent> _componentReference => DotNetObjectReference.Create(this); //Create an object reference for JS
    
        protected override async Task OnAfterRenderAsync(bool firstRender)
        {
            await JsRuntime.InvokeVoidAsync("MyJS.CacheMyComponent", _componentReference); //Send object reference to JS to cache
        }
    
        [JSInvokable("ChangeTab")]
        public async Task ChangeTab(string val)
        {
            //do something
        }
    }
    

    JavaScript

    window.MyJS = {
        MyComponentReference: null,
        CacheMyComponent: function (componentReference) {
            MyJS.MyComponentReference = componentReference; //Cache
        },
        ChangeTabOnMyComponent: function (tabText) {
            MyJS.MyComponentReference.invokeMethodAsync('ChangeTab', tabText); //Use cached reference
        }
    }
    

    【讨论】:

      【解决方案2】:

      您需要将组件的 DotNetObjectReference 传递给 JavaScript。这通常在组件渲染后完成。

      Example.razor:

      @implements IDisposable
      @inject IJSRuntime JS
      
      @code {
          private DotNetObjectReference<Example>? dotNetHelper;
      
          protected override async Task OnAfterRenderAsync(bool firstRender)
          {
              if (firstRender)
              {
                  dotNetHelper = DotNetObjectReference.Create(this);
                  await JS.InvokeVoidAsync("Helpers.setDotNetHelper", dotNetHelper);
              }
          }
      
          [JSInvokable("ChangeTab")]
          public async Task ChangeTab(string val)
          {
              ActivatePage(val);
          }
      
          public void Dispose()
          {
              dotNetHelper?.Dispose();
          }
      }
      

      然后使用该引用从 JavaScript 调用您的组件方法:

      <script>
        class Helpers {
          static dotNetHelper;
      
          static setDotNetHelper(value) {
            Helpers.dotNetHelper = value;
          }
      
          static async changeTab(tabText) {
            await Helpers.dotNetHelper.invokeMethodAsync('ChangeTab', tabText);
          }
        }
      
        window.GreetingHelpers = GreetingHelpers;
      </script>
      

      Documentation

      【讨论】:

        猜你喜欢
        • 2021-04-15
        • 2021-11-12
        • 2012-09-05
        • 1970-01-01
        • 2011-12-30
        • 2012-05-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多