简体   繁体   中英

Include JavaScript component into Blazor component

I am just starting with Blazor, trying to set up some simple project to see how to interact with different parts and components. I have been trying to include dhtmlxGantt into Blazor index page. It seems to be working by replacing index.html content with example from dhtmlxGantt. However as a result I get only gantt chart without any other Blazor components. How to do it in a proper way so that as a result I would see gantt chart on first page index.razor?

index.html:

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
  <title>DHX.Gantt</title>
  <base href="/" />
  <link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
  <link href="css/app.css" rel="stylesheet" />
  <link href="DHX.Gantt.styles.css" rel="stylesheet" />
  <link href="manifest.json" rel="manifest" />
  <link href="https://cdn.dhtmlx.com/gantt/edge/dhtmlxgantt.css" rel="stylesheet" type="text/css" />
  <script src="https://cdn.dhtmlx.com/gantt/edge/dhtmlxgantt.js"></script>
  <script>
    document.addEventListener("DOMContentLoaded", function (event) {
      // specifying the date format
      gantt.config.date_format = "%Y-%m-%d %H:%i";
      // initializing gantt
      gantt.init("gantt_here");

      // initiating data loading
      gantt.load("/api/data");
      // initializing dataProcessor
      var dp = new gantt.dataProcessor("/api/");
      // and attaching it to gantt
      dp.init(gantt);
      // setting the REST mode for dataProcessor
      dp.setTransactionMode("REST");
    });
  </script>
  <link rel="apple-touch-icon" sizes="512x512" href="icon-512.png" />
</head>

<body>
  <div id="app">Loading...</div>

  <div id="blazor-error-ui">
    An unhandled error has occurred.
    <a href="" class="reload">Reload</a>
    <a class="dismiss">🗙</a>
  </div>
  <script src="_framework/blazor.webassembly.js"></script>
  <script>navigator.serviceWorker.register('service-worker.js');</script>
</body>

</html>

Index.razor

@page "/"
@inject IJSRuntime jsRuntime

<h1>Hello, world!</h1>

Welcome to your new app. OOOO 1123154

<SurveyPrompt Title="How is Blazor working for you? jjjj" />

<div id="gantt_here" style="width: 100%; height: 100vh;"></div>

@code{
}

Basically I need to get below part into Index.razor somehow, otherwise gantt chart on Index.razor could not find necessary resources:

  <script src="https://cdn.dhtmlx.com/gantt/edge/dhtmlxgantt.js"></script>
  <script>
    document.addEventListener("DOMContentLoaded", function (event) {
      // specifying the date format
      gantt.config.date_format = "%Y-%m-%d %H:%i";
      // initializing gantt
      gantt.init("gantt_here");

      // initiating data loading
      gantt.load("/api/data");
      // initializing dataProcessor
      var dp = new gantt.dataProcessor("/api/");
      // and attaching it to gantt
      dp.init(gantt);
      // setting the REST mode for dataProcessor
      dp.setTransactionMode("REST");
    });
  </script>

Consider injecting the javascript so that it runs immediately after Blazor starts on the page.

One way we may be able to accomplish this is by changing the way Blazor begins when the page is first loaded.

In wwwroot/index.html (Blazor WebAssembly) or Pages/_Host.cshtml (Blazor Server) we can modify the Blazor initializing to invoke a script after Blazor starts.

For Example (Blazor WebAssembly):

<body>
    <!-- The Rest of the wwwroot/index.html -->
    <script src="https://cdn.dhtmlx.com/gantt/edge/dhtmlxgantt.js"></script>
    <script src="_framework/blazor.{webassembly|server}.js" 
        autostart="false"></script>
    <script>
      Blazor.start().then(function () {
          // specifying the date format
          gantt.config.date_format = "%Y-%m-%d %H:%i";
          // initializing gantt
          gantt.init("gantt_here");

          // initiating data loading
          gantt.load("/api/data");
          // initializing dataProcessor
          var dp = new gantt.dataProcessor("/api/");
          // and attaching it to gantt
          dp.init(gantt);
          // setting the REST mode for dataProcessor
          dp.setTransactionMode("REST");
      });
    </script>
</body>

An alternative option could be, if you need to arbitrarily invoke this function dynamically(on different components for example). You could create a local .js javascript file in wwwroot/MyCustomScript.js and import https://cdn.dhtmlx.com/gantt/edge/dhtmlxgantt.js and create a method to initialize dhtmlxgantt that we can call from any component using IJSRuntime .

For example: wwwroot/MyCustomScript.js

import 'https://cdn.dhtmlx.com/gantt/edge/dhtmlxgantt.js';

export function InitDHTML() {
    // specifying the date format
    gantt.config.date_format = "%Y-%m-%d %H:%i";
    // initializing gantt
    gantt.init("gantt_here");

    // initiating data loading
    gantt.load("/api/data");
    // initializing dataProcessor
    var dp = new gantt.dataProcessor("/api/");
    // and attaching it to gantt
    dp.init(gantt);
    // setting the REST mode for dataProcessor
    dp.setTransactionMode("REST");
}

The we can call that method from any component using IJSRuntime .

For example: Pages/Index.razor

// inject the runtime so we can import javascript from local files
@inject IJSRuntime JS

@{
    private IJSObjectReference importedDHTML;
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            // import the script from the file
            importedDHTML = await JS.InvokeAsync<IJSObjectReference>(
                "import", "./MyCustomScript.js");

            // Initialize dhtmlxgantt
            await importedDHTML.InvokeAsync<IJSObjectReference>(
                "InitDHTML");
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM