【问题标题】:How to Invoke Js file once data is loaded in Blazor在 Blazor 中加载数据后如何调用 Js 文件
【发布时间】:2022-08-22 14:03:56
【问题描述】:

正在调用 api 在异步任务 OnAfterRenderAsync(bool firstRender) 下加载数据 但是 jscript 在用户加载到 UI 之前加载

一旦数据加载到用户列表中,我如何调用 js?

背后的代码

protected override async Task OnAfterRenderAsync(bool firstRender)
{
   List<User> users = await Getuser(Request);
   await jsRuntime.InvokeAsync<IJSObjectReference>(\"import\", \"/js/scripts/test.js\");
}

用户界面

  <div class=\"user-list\">
    <ul>
      @foreach (var user in users)
       {
         <li>
          <h5 class=\"mb-25\">@user.name</h5>                               
         </li>
       }
    </ul>
  <div>

    标签: javascript jquery blazor


    【解决方案1】:

    在 OnAfterRenderAsync() 方法中,您将用户数据(从 API)加载到局部变量。您的 foreach 循环适用于组件中声明的另一个列表。

    利用:

    users = await Getuser(Request);
    

    代替:

    List<User> users = await Getuser(Request);
    

    【讨论】:

      【解决方案2】:

      使用OnInitializedAsync 检索数据并使用OnAfterRenderAsync 进行js 互操作。

      在 test.js 中,您必须导出添加点击事件的函数:

      export function addClickEvents() {
          // add your js code here
          if ($('.user-list').find('li').length) { $('.user-list').find('li').on('click', function (e) { $('.details').toggleClass('show'); }); }
      }
      

      然后在导入 js 模块后,你必须调用这个函数:

      private List<User> users;
      
      protected override async Task OnInitializedAsync()
      {
          users = await Getuser(Request);
      }
      
      protected override async Task OnAfterRenderAsync(bool firstRender)
      {
          if (firstRender)
          {
              var module = await jsRuntime.InvokeAsync<IJSObjectReference>("import", "/js/scripts/test.js");
              
              // invoke addClickEvents function
              await module.InvokeVoidAsync("addClickEvents");
          }
      }
      

      同样在 UI 中,您应该检查列表是否为空。

      @if (users != null)
      {
        <div class="user-list">
          <ul>
            @foreach (var user in users)
            {
              <li>
                <h5 class="mb-25">@user.name</h5>                               
              </li>
            }
          </ul>
        <div>
      }
      else
      {
        <p>Loading...</p>
      }
      

      Blazor component lifecycle

      【讨论】:

      • 我试过但仍然是同样的问题。在我的 jscript 文件中,我在 li 元素上添加了点击事件。 if $('.user-list').find('li').length) { $('.user-list').find('li').on('click', function (e) { $ ('.details').toggleClass('show'); }); }
      • 现在在代码中您只导入 js 模块。您需要在模块中有一个导出函数,然后从 C# 调用它。我更新了我的答案。顺便说一句,在不使用 jsinterop 的情况下实现它可能会更容易和更干净。
      【解决方案3】:

      我认为您想在导入 js 文件之前将用户呈现到 UI,如果这是您想要的,您需要在使用 StateHasChanged() 获取用户列表后强制组件将更改应用于用户列表:

      后面的代码:

      private List<User> users;
      protected override async Task OnAfterRenderAsync(bool firstRender)
      {
         users = await Getuser(Request);
         StateHasChanged(); // you need to use StateHasChanged to apply changes
         //await Task.Delay(0); // this will give the main thread a chance to apply changes but as the below call is also async operation, you might not need to delay to apply changes
         //So first try without delay, if it is not worked try with delay
         await jsRuntime.InvokeAsync<IJSObjectReference>("import", "/js/scripts/test.js");
      }
      

      用户界面:

      <div class="user-list">
          <ul>
            @foreach (var user in users ?? Enumerable.Empty<User>()) @*supply empty Enumerable if list is null*@
             {
               <li>
                <h5 class="mb-25">@user.name</h5>                               
               </li>
             }
          </ul>
        <div>
      

      【讨论】:

        猜你喜欢
        • 2021-08-13
        • 2019-01-23
        • 2019-04-23
        • 2021-09-21
        • 2020-08-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多