【问题标题】:How to use jQuery UI from Blazor component如何在 Blazor 组件中使用 jQuery UI
【发布时间】:2019-06-13 22:30:16
【问题描述】:

我正在研究一些 Blazor 示例,在尝试使用一些 JSInterop 解决方案时,我遇到了 jQuery UI 元素的问题。我不是一个精通 Javascript 程序员,但我对 .NET 足够精通,所以我可能会遗漏一些简单的东西。我尝试使用的第一个 jQuery UI 组件是“可调整大小”组件,可在此处找到:https://jqueryui.com/resizable/

这是我当前的代码:

index.html:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width">
    <base href="/" />
    <link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
    <link href="css/site.css" rel="stylesheet" />
    <script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.3.1.min.js"></script>
    <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
</head>
<body>
    <app>Loading...</app>

    <script src="_framework/blazor.server.js"></script>
    <script>
        $( function() {
            $( "#resizable" ).resizable();
        });
    </script>
</body>
</html>

我确定问题不在于加载库,我在加载 blazor.server.js 后放置了脚本。

现在,我的 Index.cshtml 在 html 部分有以下内容:

<body>
    <div class="container-fluid">
        <div id="resizable" class="ui-widget-content">
            <div class="row row-no-gutters" style="width: 100%; height: 50%">
                <h3 class="ui-widget-header">Resizable</h3>
            </div>
        </div>
    </div>
</body>

理想情况下,这将产生一个可调整大小的 div,但生成的 html 元素不可调整大小。据我了解,Blazor JSInterop 不再需要注册 JS 函数。我做错了什么?

【问题讨论】:

    标签: javascript jquery asp.net blazor


    【解决方案1】:

    问题在于时间问题:您的 jQuery 函数在您的 Blazor 应用程序渲染之前执行。

    我解决此问题的方法是将“onready”($(...)) 函数替换为命名函数(例如 onBlazorReady),然后在适当的时候从 Blazor 的 MainLayout 组件调用该函数。

    正确的时间是OnAfterRender

    例如:

    MainLayout.razor:

    @code {
       [Inject]
       protected IJSRuntime JsRuntime { get; set; }
    
       protected override void OnAfterRender(bool firstRender)
       {
           if (firstRender)
               JsRuntime.InvokeVoidAsync("onBlazorReady");
       }
    }
    

    index.html:

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width">
        <base href="/" />
        <link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
        <link href="css/site.css" rel="stylesheet" />
        <script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.3.1.min.js"></script>
        <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
    </head>
    <body>
        <app>Loading...</app>
    
        <script src="_framework/blazor.server.js"></script>
        <script>
            onBlazorReady() {
                $("#resizable").resizable();
            });
        </script>
    </body>
    </html>
    

    如您所见,我正在注入 IJSInterop,以便在 LayoutComponent 渲染后调用我的 onBlazorReady JS 函数。

    【讨论】:

    • 这个例子行不通? blazorfiddle.com/s/kg13ms5x
    • 我提供了代码来显示在哪里放置什么 - 不是作为一个功能齐全的示例 - 你需要一个完整的项目才能解决问题。
    • @Isaac 需要解释一下吗?
    • 我已经尝试了所有这些,但似乎没有一个适用于我的代码。我有一个 Blazor WASM PWA。在我的函数中,我添加了以下行:prompt('hey');它出现在页面仍显示“正在加载...”时。所以,我知道我的 C# 代码正在调用正确的函数,但我的动画没有显示出来。我猜这仍然是时间问题,但我找不到任何其他要使用的生命周期事件。可能是 WASM 和/或 PWA 会干扰动画吗?布拉德
    【解决方案2】:

    像这样对我来说很好,从 jquery ui 添加日期选择器:

    Razor 组件文件。

    @code {
        protected override async void OnAfterRender(bool firstRender)
        {
            await jsRuntime.InvokeVoidAsync("addDatePicker");
            base.OnAfterRender(firstRender);
        }
    }
    

    全局剃须刀文件:

    @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Magiro.Blazor</title>
        <base href="~/" />
        <link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
        <link href="css/site.css" rel="stylesheet" />
        <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
        <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
        <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
    </head>
    <body>
        <app>
            @(await Html.RenderComponentAsync<App>(RenderMode.ServerPrerendered))
        </app>
    
        <script src="_framework/blazor.server.js"></script>
        <script>
            window.addDatePicker = () => {
                $(".datepicker").datepicker();
            }
        </script>
    </body>
    </html>
    

    【讨论】:

      【解决方案3】:

      最可能的原因是时机。 jQuery 函数在 DOM 元素存在之前被执行。

      您应该将 JS 代码注册为互操作函数,然后在 OnAfterRender 事件中调用它。

      【讨论】:

      • 即使我没有从 C# 方法调用 jQuery 函数?基本上只是一个名为OnAfterRender() 的新覆盖方法,它返回JSRuntime.Current.InvokeAsync(“resizable”) 等?
      • 是的,这将确保函数在 DOM 元素存在时运行。在你的例子中,我很确定时间是问题所在。
      • 好的,我早上试试。我没想到 - 谢谢你的建议!
      • 我建议你睡在上面...考虑到可调整大小的方法应该在命名空间中定义为:window.somenamespace.somemethod...祝你好运...跨度>
      【解决方案4】:

      不再需要在全局索引页面(ASP.NET Core 5.0 中的_Hosts.cshtml)中添加方法,该方法将使用特定于视图的逻辑和依赖项填充这些文件。至少在 v5 中,我们有IJSObjectReference 允许我们直接从我们的.razor 文件中调用$('table').DataTable(),如下所示:

      <table>
          <thead>
              <tr>
                  <td>Id</td>
                  <td>Name</td>
              </tr>
          </thead>
          <tbody>
                  <!-- your data -->
          </tbody>
      </table>
      
      @code {
          [Inject]
          protected IJSRuntime JSRuntime { get; set; }
      
          protected override async Task OnAfterRenderAsync(bool firstRender) {
              if (firstRender) {
                  var jQuery = await JSRuntime.InvokeAsync<IJSObjectReference>("$", "table");
                  await jQuery.InvokeVoidAsync("DataTable");
              }
          }
      }
      

      也可以使用匿名类型将选项传递给插件。例如,要禁用搜索,我们会在 JS 中调用

      $('#example').dataTable({
        "searching": false
      });
      

      在 Blazor 中,我们创建一个具有相同结构的匿名类型,并将其作为参数传递给 DataTable 调用:

      var options = new {
          searching = false
      };
      await jQuery.InvokeVoidAsync("DataTable", options);
      

      【讨论】:

        【解决方案5】:

        通常您不需要像ready 这样的任何 JQuery 函数,您可以简单地将所有必需的代码放入您的自定义 js 函数中,该函数应该在您的组件的 ON_LOAD 上运行,如上述答案中@Sipke Schoorstra 所说的

        【讨论】:

          猜你喜欢
          • 2020-12-14
          • 1970-01-01
          • 2021-03-26
          • 1970-01-01
          • 2021-02-20
          • 1970-01-01
          • 2020-09-12
          • 2018-09-25
          • 2013-07-19
          相关资源
          最近更新 更多