彩票走势图

甘特图控件DHTMLX Gantt 教程:dhtmlxGantt与ASP.NET Core(上)

翻译|使用教程|编辑:颜馨|2023-04-18 13:49:00.143|阅读 90 次

概述:本章讲述dhtmlxGantt在ASP.NET Core上的使用方法,欢迎查阅!

# 慧都年终大促·界面/图表报表/文档/IDE等千款热门软控件火热促销中 >>

相关链接:

DHTMLX甘特图是用于跨浏览器和超平台应用程序的功能齐备的甘特图。可满足项目管理应用程序的大部分需求,具备完善的甘特图表库,功能强大,价格方便,提供丰厚而灵活的JavaScript API接口,与各种服务端技术(PHP,ASP.NET,Java等)简单集合,满足多种定制开发需求。

DHTMLX JavaScript UI 库所开发的 JavaScript 组合易于使用和功能丰富,非常适合结合任何领导地位和任何复合性的解决方案,能力足足够省创造和维保业务应用程序的时间,提供高生产力。

DHTMLX 甘特图最新下载


本教程将逐步指导您如何使用 ASP.NET Core 在服务端创建甘特图。

第一步 创建一个项目

启动Visual Studio 2022并创建一个新的项目。选择:创建一个新的项目。

使用 ASP.NET Core 创建项目的 dhtmlxGantt

接下来来选择“ASP.NET Core Web App”并命名为DHX.Gantt。

使用 ASP.NET Core 创建项目的 dhtmlxGantt

dhtmlxGantt 使用 ASP.NET Core 配置一个项目项目

dhtmlxGantt 使用 ASP.NET Core 配置一个项目项目

自此,你已经创建了一个项目,可以继续为甘特图添加标记和脚本。

第二步 添加甘特图标记和JS

进入wwwroot并创建一个index.html文件。

dhtmlx甘特与ASP.NET核心2创建一个项目

dhtmlx甘特与ASP.NET核心2创建一个项目

在新创建的文件中,为甘特图制作一个简单的页面。

请注意,甘特图文件是在此演示中从 CDN 添加的。如果您有该组件的专业版本, 您需要手动将甘特图文件添加到项目中。

<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Index</title> <link href="//cdn.dhtmlx.com/gantt/edge/dhtmlxgantt.css" rel="stylesheet" type="text/css" /> <script src="//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> </head> <body> <div id="gantt_here" style="width: 100%; height: 100vh;"></div> </body> </html>

当页面被加载时,除了初始化甘特图的数据加载外,还立即调用dataProcessor,所以用户对甘特图的所有修改都将被保存到后台。后台还没有实现,所以以后会更有意义。
接下来进入Program.cs,告诉应用程序使用index.html页面。为了做到这一点,你需要将应用程序配置为从wwwroot文件夹中提供静态文件。为此,你需要添加app.UseDefaultFiles()方法。你可以在这里找到更多细节。

var builder = WebApplication.CreateBuilder(args);  // Add services to the container. builder.Services.AddRazorPages();  var app = builder.Build();  // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Error"); // The default HSTS value is 30 days. // You may want to change this for production scenarios, // see //aka.ms/aspnetcore-hsts. app.UseHsts(); }  app.UseHttpsRedirection();  app.UseDefaultFiles();  app.UseStaticFiles();  app.UseRouting();  app.UseAuthorization();  app.MapRazorPages();  app.Run();

该方法允许提供默认文件。它将搜索wwwroot文件夹中的以下文件:app.UseDefaultFiles()

  • index.html
  • index.htm
  • default.html
  • default.htm

因此,你可以选择其中的任何一个,而在本教程中使用的是 "index.html"。只是一个URL-rewriter,并不实际提供文件。为此,你还需要添加文件。UseDefaultFiles()UseStaticFiles()

一旦你完成了它,当你运行应用程序时,一个空的甘特图就会出现在页面上。注意,右上角的 "无效数据 "标签显示,因为因为仍然没有合适的后台来提供数据,所以被调用。当控制器实现后,gantt将能够显示任务和链接。gantt.load()

dhtmlx甘特与ASP.NET核心2添加甘特图

现在基本部分已经完成,是时候实现后端了。让我们从实现模型类开始,之后再进行WebAPI控制器。

第三步 创建模型和数据库

让我们从数据模型开始。甘特的数据模型包括链接和任务,从.NET世界的角度来看,dhtmlxGantt对模型属性使用非常规的名称。有时客户端的模型也包含一些客户端或后端逻辑的属性,但这些属性不应该存储在数据库中。

为了处理这个问题,将使用数据传输对象(DTO)模式。两种模型将被定义:

  • 领域模型类,它将被用于EF Core和应用程序内部
  • DTO类,将用于与Web API进行通信。

然后,这两种模型之间的映射应该被实现。

模型
在项目文件夹中创建一个名为Models的新文件夹。这是实现模型类和 EF 上下文的位置。

任务模型
首先,为任务创建一个类。在Models文件夹中创建一个文件,命名为Task.cs。这可以通过调用Models文件夹的上下文菜单并选择Add->Class来完成。

这个模型必须是这样的:

namespace DHX.Gantt.Models { public class Task { public int Id { get; set; } public string? Text { get; set; } public DateTime StartDate { get; set; } public int Duration { get; set; } public decimal Progress { get; set; } public int? ParentId { get; set; } public string? Type { get; set; } } }

你可以查询任务对象的所有属性列表。

链接模型
再添加一个文件,为链接创建一个类:

namespace DHX.Gantt.Models { public class Link { public int Id { get; set; } public string? Type { get; set; } public int SourceTaskId { get; set; } public int TargetTaskId { get; set; } } }

模型已经准备好了,你可以开始配置数据库连接。
为了配置数据库连接,你需要采取下面列出的步骤:

安装Entity Framework Core
Entity Framework Core将被用来管理应用程序与数据库的通信。让我们来安装该框架:

  • 在项目树中找到DHTMLX.Gantt的依赖项
  • 调用上下文菜单并选择管理NuGet包
  • 打开浏览标签并安装Microsoft.EntityFrameworkCore.SqlServer, Microsoft.EntityFrameworkCore和Microsoft.EntityFrameworkCore.Design

或者使用软件包管理器命令行:

PM> Install-Package Microsoft.EntityFrameworkCore.SqlServer PM> Install-Package Microsoft.EntityFrameworkCore PM> Install-Package Microsoft.EntityFrameworkCore.Design

实体框架核心将用来管理应用程序与数据库的通信。

创建实体上下文
接下来你需要定义一个与数据库的会话,并启用加载和保存数据。为此,创建Context:

  • 在Models文件夹中添加GanttContext.cs文件
  • 在创建的文件中定义GanttContext类
using Microsoft.EntityFrameworkCore;  namespace DHX.Gantt.Models { public class GanttContext : DbContext { public GanttContext(DbContextOptions<GanttContext> options) : base(options) { } public DbSet<Task> Tasks { get; set; } = null; public DbSet<Link> Links { get; set; } = null;  } }

向数据库添加第一批记录
现在你可以向数据库添加记录了。让我们创建数据库初始化器,将任务填充到数据库中。在Models文件夹中定义一个类,并将其称为GanttSeeder。该类将有Seed()方法,将添加任务和链接到数据库。

using Microsoft.EntityFrameworkCore;  namespace DHX.Gantt.Models { public static class GanttSeeder { public static void Seed(GanttContext context) { if (context.Tasks.Any()) { return; // DB has been seeded }  using (var transaction = context.Database.BeginTransaction()) { List<Task> tasks = new List<Task>() { new Task() { Id = 1, Text = "Project #2", StartDate = DateTime.Today.AddDays(-3), Duration = 18, Progress = 0.4m, ParentId = null }, new Task() { Id = 2, Text = "Task #1", StartDate = DateTime.Today.AddDays(-2), Duration = 8, Progress = 0.6m, ParentId = 1 }, new Task() { Id = 3, Text = "Task #2", StartDate = DateTime.Today.AddDays(-1), Duration = 8, Progress = 0.6m, ParentId = 1 } };  tasks.ForEach(s => context.Tasks.Add(s)); context.Database.ExecuteSqlRaw("SET IDENTITY_INSERT Tasks ON;"); context.SaveChanges();  context.Database.ExecuteSqlRaw("SET IDENTITY_INSERT Tasks OFF;"); List<Link> links = new List<Link>() { new Link() {Id = 1, SourceTaskId = 1, TargetTaskId = 2, Type = "1"}, new Link() {Id = 2, SourceTaskId = 2, TargetTaskId = 3, Type = "0"} };  links.ForEach(s => context.Links.Add(s)); context.Database.ExecuteSqlRaw("SET IDENTITY_INSERT Links ON;"); context.SaveChanges(); context.Database.ExecuteSqlRaw("SET IDENTITY_INSERT Links OFF;"); transaction.Commit(); } } } }

注册数据库
现在你应该在Program.cs中注册数据库。但首先你需要一个连接字符串。它将被存储在应用程序设置的JSON文件中。创建appsettings.json文件(如果你已经有了,则打开它),并为数据库添加一个连接字符串:

{ "ConnectionStrings": { "DefaultConnection": "Server=(localdb)\\mssqllocaldb; Database=GanttDatabase;Trusted_Connection=True;" } }

数据库上下文将通过依赖关系注入进行注册。
将以下命名空间添加到 Program.cs:

using Microsoft.EntityFrameworkCore; using DHX.Gantt.Models;

该声明将看起来像这样:

var connectionString = builder.Configuration.GetConnectionString("DefaultConnection"); builder.Services.AddDbContext<GanttContext>( options => options.UseSqlServer(connectionString));

要启用控制器,需要调用services.AddControllers()方法:

builder.Services.AddControllers();

然后我们调用app.MapControllers()来注册我们的控制器路线:

app.MapControllers();

下面是Program.cs的完整代码:

using Microsoft.EntityFrameworkCore; using DHX.Gantt.Models;  var builder = WebApplication.CreateBuilder(args);  // Add services to the container. builder.Services.AddRazorPages();  var connectionString = builder.Configuration.GetConnectionString("DefaultConnection"); builder.Services.AddDbContext<GanttContext>( options => options.UseSqlServer(connectionString));  builder.Services.AddControllers();  var app = builder.Build();  // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Error"); // The default HSTS value is 30 days. // You may want to change this for production scenarios, // see //aka.ms/aspnetcore-hsts. app.UseHsts(); }  app.UseHttpsRedirection();  app.UseDefaultFiles();  app.UseStaticFiles();  app.UseRouting();  app.UseAuthorization();  app.MapRazorPages();  app.MapControllers();  app.Run(); 

最后,你需要在应用启动时初始化和播种数据库。通常情况下,你会希望使用迁移来完成这个任务,但为了简单起见,这里没有使用迁移。

让我们首先创建一个初始化的类。在Models文件夹中创建GanttInitializerExtension.cs文件:

namespace DHX.Gantt.Models { public static class GanttInitializerExtension { public static IHost InitializeDatabase(this IHost webHost) { var serviceScopeFactory = (IServiceScopeFactory?)webHost.Services.GetService(typeof(IServiceScopeFactory));  using (var scope = serviceScopeFactory!.CreateScope()) { var services = scope.ServiceProvider; var dbContext = services.GetRequiredService<GanttContext>(); dbContext.Database.EnsureDeleted(); dbContext.Database.EnsureCreated(); GanttSeeder.Seed(dbContext); }  return webHost; } } }

接下来调用InitializeDatabase():

app.InitializeDatabase();

正如上面提到的,本教程中没有使用迁移。而是使用简单的EnsureCreated和种子。

当前部分已经完成,让我们回到甘特图。

定义DTOs和映射
现在是定义将用于Web API的DTO类的时候了。让我们从任务的DTO类开始。在Models文件夹中创建一个文件并定义WebApiTask.cs类:

namespace DHX.Gantt.Models { public class WebApiTask { public int id { get; set; } public string? text { get; set; } public string? start_date { get; set; } public int duration { get; set; } public decimal progress { get; set; } public int? parent { get; set; } public string? type { get; set; } public bool open { get { return true; } set { } }  public static explicit operator WebApiTask(Task task) { return new WebApiTask { id = task.Id, text = task.Text, start_date = task.StartDate.ToString("yyyy-MM-dd HH:mm"), duration = task.Duration, parent = task.ParentId, type = task.Type, progress = task.Progress }; }  public static explicit operator Task(WebApiTask task) { return new Task { Id = task.id, Text = task.text, StartDate = task.start_date != null ? DateTime.Parse(task.start_date, System.Globalization.CultureInfo.InvariantCulture) : new DateTime(), Duration = task.duration, ParentId = task.parent, Type = task.type, Progress = task.progress }; } } }

而这是定义在Models文件夹中名为WebApiLink.cs的文件中的Link的DTO类:

namespace DHX.Gantt.Models { public class WebApiLink { public int id { get; set; } public string? type { get; set; } public int source { get; set; } public int target { get; set; }  public static explicit operator WebApiLink(Link link) { return new WebApiLink { id = link.Id, type = link.Type, source = link.SourceTaskId, target = link.TargetTaskId }; }  public static explicit operator Link(WebApiLink link) { return new Link { Id = link.id, Type = link.type, SourceTaskId = link.source, TargetTaskId = link.target }; } } }

当你完成这一步骤时,你应该得到以下的文件夹结构:

甘特图 ASP.NET Core 2 所有型号

现在你可以运行该应用程序,以检查一切是否到位。如果你没有看到一个运行时错误,那么一切都很好。

第四步 实现网络API

现在是实际实现REST API的时候了。

添加控制器
创建控制器文件夹并创建三个空的API控制器:一个用于任务,另一个用于链接,还有一个用于整个数据集:

甘特图 ASP.NET Core 2 添加控制器

任务控制器
让我们为任务创建一个控制器。它将定义甘特任务的基本CRUD操作。

它是如何工作的:

在GET请求中,任务从数据库加载,输出是任务的数据传输对象;
在PUT/POST请求中,任务作为WebAPITask类来自客户端。它们在dhtmlxGantt中以这种方式表示。因此,你应该把它们转换为我们的EntityFramework数据模型的格式(任务类)。之后,就可以在DatabaseContext中保存更改。

using Microsoft.AspNetCore.Mvc; using DHX.Gantt.Models;  namespace DHX.Gantt.Controllers { [Produces("application/json")] [Route("api/task")] public class TaskController : Controller { private readonly GanttContext _context; public TaskController(GanttContext context) { _context = context; }  // GET api/task [HttpGet] public IEnumerable<WebApiTask> Get() { return _context.Tasks .ToList() .Select(t => (WebApiTask)t); }  // GET api/task/5 [HttpGet("{id}")] public Models.Task? Get(int id) { return _context .Tasks .Find(id); }  // POST api/task [HttpPost] public ObjectResult Post(WebApiTask apiTask) { var newTask = (Models.Task)apiTask;  _context.Tasks.Add(newTask); _context.SaveChanges();  return Ok(new { tid = newTask.Id, action = "inserted" }); }  // PUT api/task/5 [HttpPut("{id}")] public ObjectResult? Put(int id, WebApiTask apiTask) { var updatedTask = (Models.Task)apiTask; var dbTask = _context.Tasks.Find(id); if (dbTask == null) { return null; } dbTask.Text = updatedTask.Text; dbTask.StartDate = updatedTask.StartDate; dbTask.Duration = updatedTask.Duration; dbTask.ParentId = updatedTask.ParentId; dbTask.Progress = updatedTask.Progress; dbTask.Type = updatedTask.Type;  _context.SaveChanges();  return Ok(new { action = "updated" }); }  // DELETE api/task/5 [HttpDelete("{id}")] public ObjectResult DeleteTask(int id) { var task = _context.Tasks.Find(id); if (task != null) { _context.Tasks.Remove(task); _context.SaveChanges(); }  return Ok(new { action = "deleted" }); } } }

链接控制器
接下来你应该为链接创建一个控制器:

using Microsoft.EntityFrameworkCore; using Microsoft.AspNetCore.Mvc; using DHX.Gantt.Models;  namespace DHX.Gantt.Controllers { [Produces("application/json")] [Route("api/link")] public class LinkController : Controller { private readonly GanttContext _context; public LinkController(GanttContext context) { _context = context; }  // GET api/Link [HttpGet] public IEnumerable<WebApiLink> Get() { return _context.Links .ToList() .Select(t => (WebApiLink)t); }  // GET api/Link/5 [HttpGet("{id}")] public Link? Get(int id) { return _context .Links .Find(id); }  // POST api/Link [HttpPost] public ObjectResult Post(WebApiLink apiLink) { var newLink = (Link)apiLink;  _context.Links.Add(newLink); _context.SaveChanges();  return Ok(new { tid = newLink.Id, action = "inserted" }); }  // PUT api/Link/5 [HttpPut("{id}")] public ObjectResult Put(int id, WebApiLink apiLink) { var updatedLink = (Link)apiLink; updatedLink.Id = id; _context.Entry(updatedLink).State = EntityState.Modified;   _context.SaveChanges();  return Ok(new { action = "updated" }); }  // DELETE api/Link/5 [HttpDelete("{id}")] public ObjectResult DeleteLink(int id) { var Link = _context.Links.Find(id); if (Link != null) { _context.Links.Remove(Link); _context.SaveChanges(); }  return Ok(new { action = "deleted" }); } } }

数据控制器
最后,你需要为一个数据动作创建一个控制器:

using Microsoft.AspNetCore.Mvc; using DHX.Gantt.Models;  namespace DHX.Gantt.Controllers { [Produces("application/json")] [Route("api/data")] public class DataController : Controller { private readonly GanttContext _context; public DataController(GanttContext context) { _context = context; }  // GET api/data [HttpGet] public object Get() { return new { 数据 = _context.Tasks.ToList().Select(t => (WebApiTask)t), 链接 = _context.Links.ToList().Select(l => (WebApiLink)l)  }; }  } }

一切都准备好了。你可以运行该应用程序,看到成熟的甘特图。

甘特图 ASP.NET Core 甘特图已准备就绪

你也可以在 GitHub 上查看完整的源代码。

DHTMLX甘特图享有超过十年的声望,支持跨浏览器和跨平台,性能比高,可满足项目管理应用程序的所有需求,是最擅长的甘特图表库。


甘特图控件交流群:764148812

欢迎加入群交流讨论,获得更多帮助请联系


标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@cahobeh.cn


为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP