如何将jQuery添加到Blazor Server应用程序中?

发布于 2025-02-09 07:36:34 字数 4548 浏览 1 评论 0原文

我正在尝试将一些jQuery添加到Blazor Server应用程序中。特别是能够在剃须刀页面(createNote.razor)上的表单上(其中ID ='CompanyName')上自动完成输入字段。当我运行该应用程序时,AutoComplete行不通。我添加了警报线以测试是否执行并且效果很好。

_layout.cshtml:

...
</head>
    <link href="TelephoneNotes.styles.css" rel="stylesheet" />

    <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
    <script src="https://code.jquery.com/ui/1.13.1/jquery-ui.min.js" integrity="sha256-eTyxS0rkjpLEo16uXTS0uVCS4815lc40K2iVpWDvdSY=" crossorigin="anonymous"></script>

    <link href="https://tofsjonas.github.io/sortable/sortable.css" rel="stylesheet" />
    <script src="https://tofsjonas.github.io/sortable/sortable.js"></script>

    <script type="text/javascript">$(function () {
            $("#companyName").autocomplete({
                source: ["Apple", "Google", "Facebook"],
                minLength: 3
            })

    $(document).ready(function () {
        alert("test");
    });

        })</script>
    <component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" />
</head>

createNote.Razor:

<EditForm Model="@newNote" OnSubmit="@InsertNote">
...
    <div class="form-group row" style="padding-top: 5px;">
        <label for="company" class="col-sm-2 col-form-label">
            Company:
        </label>
        <div class="col-sm-10">
            <InputText id="companyName" class="form-control" placeholder=""
                       @bind-Value="newNote.CompanyName" />
        </div>
    </div>
...
</EditForm>

更新:

我已经使用init.js使用wwwroot文件夹:

function CompleteFormControls() {
    $("#companyName").autocomplete({
        source: ["Apple", "Google", "Facebook"],
        minLength: 3
    }

我已经在_layout的底部添加了以下行。 CSHTML在关闭主体标签之前:

<script src="/init.js"></script>

我创建了jsinterop class:

namespace TelephoneNotes.Services
{
    using Microsoft.JSInterop;

    public class JSInterop
    {
        private readonly IJSRuntime js;

        public JSInterop(IJSRuntime js)
        {
            this.js = js;
        }

        public async ValueTask InvokeCompleteFormControls()
        {
            await js.InvokeVoidAsync("CompleteFormControls");
        }

        public void Dispose()
        {
        }
    }
}

createNote.razor:

@page "/createnote"

<PageTitle>Create Note</PageTitle>

@using TelephoneNotes.Data
@inject NotesService NotesService
@implements IDisposable
@inject IJSRuntime JS

<h1>Create Note</h1>

<EditForm Model="@newNote" OnSubmit="@InsertNote">
    <div class="form-group row" style="padding-top: 5px;">
        <label for="company" class="col-sm-2 col-form-label">
            Company:
        </label>
        <div class="col-sm-10">
            <InputText id="companyName" class="form-control" placeholder=""
                       @bind-Value="newNote.CompanyName" />
        </div>
    </div>

    <div class="form-group row" style="padding-top: 15px;">
        <button type="submit" class="btn btn-primary">Submit</button>
    </div>
</EditForm>

@code {
    private List<string?> companyNames = new List<string?>();
    private TelephoneNotes.Services.JSInterop? jsClass;

    protected override async Task OnInitializedAsync()
    {
        jsClass = new(JS);
        companyNames = await NotesService.GetCompanyNames();
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            await jsClass.InvokeCompleteFormControls();
        }
    }

    public void Dispose() => jsClass?.Dispose();
}

但是,当我运行应用程序并转到“创建注释”页面时,我会收到以下错误:

Error: Microsoft.JSInterop.JSException: Could not find 'CompleteFormControls' ('CompleteFormControls' was undefined).

任何建议:为什么?

_host.cshtml:

@page "/"
@namespace TelephoneNotes.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
    Layout = "_Layout";
}

<component type="typeof(App)" render-mode="ServerPrerendered" />
<script src="/init.js"></script>

I'm attempting to add some jQuery to a Blazor server app. Specifically being able to autocomplete an InputText field on a form (where id = 'CompanyName') which is on a razor page (CreateNote.razor). When I run the app, autocomplete doesn't work. I've added the alert line to test if that executes and that works fine.

_Layout.cshtml:

...
</head>
    <link href="TelephoneNotes.styles.css" rel="stylesheet" />

    <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
    <script src="https://code.jquery.com/ui/1.13.1/jquery-ui.min.js" integrity="sha256-eTyxS0rkjpLEo16uXTS0uVCS4815lc40K2iVpWDvdSY=" crossorigin="anonymous"></script>

    <link href="https://tofsjonas.github.io/sortable/sortable.css" rel="stylesheet" />
    <script src="https://tofsjonas.github.io/sortable/sortable.js"></script>

    <script type="text/javascript">$(function () {
            $("#companyName").autocomplete({
                source: ["Apple", "Google", "Facebook"],
                minLength: 3
            })

    $(document).ready(function () {
        alert("test");
    });

        })</script>
    <component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" />
</head>

CreateNote.razor:

<EditForm Model="@newNote" OnSubmit="@InsertNote">
...
    <div class="form-group row" style="padding-top: 5px;">
        <label for="company" class="col-sm-2 col-form-label">
            Company:
        </label>
        <div class="col-sm-10">
            <InputText id="companyName" class="form-control" placeholder=""
                       @bind-Value="newNote.CompanyName" />
        </div>
    </div>
...
</EditForm>

UPDATE:

I've created an init.js with the wwwroot folder:

function CompleteFormControls() {
    $("#companyName").autocomplete({
        source: ["Apple", "Google", "Facebook"],
        minLength: 3
    }

I've added the following line to the bottom of _Layout.cshtml before the closing body tag:

<script src="/init.js"></script>

I've create a JSInterop class:

namespace TelephoneNotes.Services
{
    using Microsoft.JSInterop;

    public class JSInterop
    {
        private readonly IJSRuntime js;

        public JSInterop(IJSRuntime js)
        {
            this.js = js;
        }

        public async ValueTask InvokeCompleteFormControls()
        {
            await js.InvokeVoidAsync("CompleteFormControls");
        }

        public void Dispose()
        {
        }
    }
}

CreateNote.razor:

@page "/createnote"

<PageTitle>Create Note</PageTitle>

@using TelephoneNotes.Data
@inject NotesService NotesService
@implements IDisposable
@inject IJSRuntime JS

<h1>Create Note</h1>

<EditForm Model="@newNote" OnSubmit="@InsertNote">
    <div class="form-group row" style="padding-top: 5px;">
        <label for="company" class="col-sm-2 col-form-label">
            Company:
        </label>
        <div class="col-sm-10">
            <InputText id="companyName" class="form-control" placeholder=""
                       @bind-Value="newNote.CompanyName" />
        </div>
    </div>

    <div class="form-group row" style="padding-top: 15px;">
        <button type="submit" class="btn btn-primary">Submit</button>
    </div>
</EditForm>

@code {
    private List<string?> companyNames = new List<string?>();
    private TelephoneNotes.Services.JSInterop? jsClass;

    protected override async Task OnInitializedAsync()
    {
        jsClass = new(JS);
        companyNames = await NotesService.GetCompanyNames();
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            await jsClass.InvokeCompleteFormControls();
        }
    }

    public void Dispose() => jsClass?.Dispose();
}

However when I run the app and go to the create note page, I receive the following error:

Error: Microsoft.JSInterop.JSException: Could not find 'CompleteFormControls' ('CompleteFormControls' was undefined).

Any suggestions why?

_Host.cshtml:

@page "/"
@namespace TelephoneNotes.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
    Layout = "_Layout";
}

<component type="typeof(App)" render-mode="ServerPrerendered" />
<script src="/init.js"></script>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

你是年少的欢喜 2025-02-16 07:36:35

您无法在julazor中使用这样的JS。

什么是$(document).ready(){}
这意味着此范围内的代码{}只能渲染,并且只有在页面DOM准备执行JS代码后才进行。

何时准备在大火中准备?
在大多数情况下,您必须在Bult-In onfterRender函数中执行JS代码,因为在这一点上,您将确保DOM已完成,并且可以使用JS来操纵前端。

执行JS函数的最佳方法是什么?

  1. wwwroot文件夹中的JS创建一个单独的文件(myjs.js)和在此处添加您的JS功能。

     函数plottyformControls()
    {
      settimeout(()=&gt; {
        if($(“#companyName”)!= null){
          $(“#CompanyName”)。autoComplete({
          资料来源:[“ Apple”,“ Google”,“ Facebook”],
          最低:3});
        }
     },500);
    }
     
  2. 在_host.html的主体末端添加js文件'myjs.js',它应该是jquery

    的下降。

     &lt; Body&gt;
     &lt; script src =“〜/lib/jquery/jquery.min.js”&gt;&lt;/script&gt;
     &lt; script src =“〜/myjs.js”&gt;&lt;/script&gt;
    &lt;/body&gt;
     
  3. ' myjs.js 文件:

      Puplic Statis类Jshelper
    {
     [debuggerhidden] //告诉vs不要调试此功能
     Puplic Statis aasync valueTask ploverseFormControlsAsync(this ijSruntime)
     {
      等待js.invokevoicevoidAsync(“完整formcontrols”);
     }
    } 
     
  4. 注入ijsruntime在剃须刀页面中:

      [注入]私有ijsruntime JS {get;放;}
    受保护的替代任务onfterRenderAsync(bool firstrender)
    {
      如果(firstrender)
      {
        等待JS.CompleteFormControlsAsync();
      }
    }
     

注意:您还可以替换onfterRenderAsync 并使用一些事件,例如单击事件,因为在这种情况下,您确定DOM也完成了渲染。

You can not use Js like this in Blazor.

What is $( document ).ready() {}?
It means that the code inside this scope {} will render just and only once the page DOM is ready for JS code to execute.

When is the DOM ready in Blazor?
In most cases you have to execute the JS code in the bult-in OnAfterRender function because in this point you will be sure that DOM is complete and you can use JS to manipulate the front-end.

What is the best way to execute JS functions?

  1. Create a separate file(MyJs.js) for Js in the wwwroot folder and add your JS functions there.

    function CompleteFormControls ()
    {
      setTimeout(() => {
        if($("#companyName") != null){
          $("#companyName").autocomplete({
          source: ["Apple", "Google", "Facebook"],
          minLength: 3});
        }
     },500);
    }
    
  2. Add your Js file 'MyJs.js' in the end of the body of your _Host.html and it should be down of jquery:

    <body>
     <script src="~/lib/jquery/jquery.min.js"></script>
     <script src="~/MyJs.js"></script>
    </body>
    
  3. Create a class file to represent your functions in MyJs.js file:

    puplic statis class JsHelper
    {
     [DebuggerHidden]// tell VS Don't debug this function
     puplic statis aasync ValueTask CompleteFormControlsAsync(this IJSRunTime)
     {
      await js.InvokeVoidAsync("CompleteFormControls");
     }
    } 
    
  4. Inject IJSRuntime in your razor page:

    [Inject] private IJSRuntime Js {get; set;}
    protected override Task OnAfterRenderAsync(bool firstRender)
    {
      if(firstRender)
      {
        await Js.CompleteFormControlsAsync();
      }
    }
    

Note: You can also replace OnAfterRenderAsync and use some event like Click event, because in this case you are sure that the DOM has also completed rendering.

贪恋 2025-02-16 07:36:35

将您的JavaScript放在身体标签的末端。当前的位置您所说的$(“#CompanyName”)将是无效的。在JavaScript执行之前,必须加载组件。

<html>
<body>

<Your Components will be here>

 <script type="text/javascript">$(function () {
            $("#companyName").autocomplete({
                source: ["Apple", "Google", "Facebook"],
                minLength: 3
            })

    $(document).ready(function () {
        alert("test");
    });

        })</script>
<body>
</html>

Put your javascript at the end of the body tag. The current location you've put it $("#companyName") will be null. The component has to be loaded before your javascript executes.

<html>
<body>

<Your Components will be here>

 <script type="text/javascript">$(function () {
            $("#companyName").autocomplete({
                source: ["Apple", "Google", "Facebook"],
                minLength: 3
            })

    $(document).ready(function () {
        alert("test");
    });

        })</script>
<body>
</html>
撧情箌佬 2025-02-16 07:36:35

页面/_layout.cshtml与您的JS脚本以及JS脚本一起添加以下片段:

<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script src="js/init.js"></script>

在这种情况下,您的JS脚本将在wwwroot/js文件夹中

在createNote.Razor中:

IJSRuntime _js

//other code here

@code {
protected override async Task OnAfterRenderAsync(bool firstRender)
  {
      await _js.InvokeVoidAsync("CompleteFormControls");
  }
}

In Pages/_Layout.cshtml add the following snippet to the end of the body along with your JS script:

<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script src="js/init.js"></script>

In this case your JS script will be in wwwroot/js folder

In the CreateNote.razor:

IJSRuntime _js

//other code here

@code {
protected override async Task OnAfterRenderAsync(bool firstRender)
  {
      await _js.InvokeVoidAsync("CompleteFormControls");
  }
}
§普罗旺斯的薰衣草 2025-02-16 07:36:35

Blazor不了解查询选择器'$',您需要用关键字文档替换它。

Blazor does not understand the query selector '$', you need to replace it with keyword document.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文