使用 SortableJS 组件的 Blazor 可排序列表

作者:Burke Holland
排版:Alan Wang

在 Web 应用程序中,一个常见功能部分是可排序列表。SortableJS 是我最喜欢的 JavaScript 库之一,在进行 Blazor 开发时我很想念它。为了解决这个问题,我决定包装 SortableJS 库,使其成为 Blazor 组件,名为 Blazor Sortable,我已在 GitHub 上开源了它,我相信您会喜欢它的。在这篇文章中,我将引导您了解如何将其添加到您自己的 Blazor Web 应用程序中。

注意:Blazor Sortable 是一个开源社区组件,而不是 Microsoft 的官方组件。Blazor 的 Fluent UI 团队正在致力于在即将发布的 Blazor 的 Fluent UI 版本中集成可排序组件。您现在可以尝试 Fluent UI Sortable Demo。

请在这里查看演示:https: //blazorsortable.theurlist.com
在这里插入图片描述
每周五,Jon Galloway(虽然你可能从未听说过他,但他值得信赖)和我致力于在 Blazor 中重建一个名为 theurlist.com 的应用程序。该直播在 Twitch 和 .NET YouTube 上被称为“Burke Learns Blazor”(点赞并订阅!)。如果您愿意加入我们,我们将会非常高兴。由于我不知道我们现在需要做些什么,所有我们需要尽可能多的帮助来一起处理这件事。

我们最终需要一个可排序列表组件来进行此重建,虽然有一些“Blazor Sortable”示例,但我还是很想要用 SortableJS。SortableJS 是一个出色的库,用于构建可排序的项目列表,几乎具有您可能需要的所有功能 - 排序、列表之间的排序、克隆项目、过滤、自定义动画缓动、腰部支持。好吧——最后一个不是,但这是它唯一没有的东西。

因此,在 Steve Sanderson 的帮助下,我们在 SortableJS 上构建了一个简单的抽象,您可以将其放入您自己的应用程序中并使用。让我们看一下如何为您自己的 Blazor 应用程序使用和自定义 Blazor Sortable。

使用 Blazor Sortable

Blazor Sortable 的 GitHub 存储库包含可排序列表的源代码以及演示。对于您自己的项目,您只需要 Shared/SortableList.razor、Shared/SortableList.razor.css 和 Shared/SortableList.razor.js 文件。
在这里插入图片描述
SortableList 组件是一个通用组件,它采用项目列表和定义如何呈现可排序列表中每个项目的 SortableItemTemplate。例如,假设您有一个如下所示的书籍列表…

public class Book
{public string Title { get; set; } = "";public string Author { get; set; }  = "";public int Year { get; set; }
}public List<Book> books = new List<Book>
{new Book { Title = "The Very Hungry Caterpillar", Author = "Eric Carle", Year = 1969 },new Book { Title = "Where the Wild Things Are", Author = "Maurice Sendak", Year = 1963 },new Book { Title = "Goodnight Moon", Author = "Margaret Wise Brown", Year = 1947 },new Book { Title = "The Cat in the Hat", Author = "Dr. Seuss", Year = 1957 },new Book { Title = "Charlotte's Web", Author = "E.B. White", Year = 1952 },new Book { Title = "Harry Potter and the Sorcerer's Stone", Author = "J.K. Rowling", Year = 1997 },new Book { Title = "The Lion, the Witch and the Wardrobe", Author = "C.S. Lewis", Year = 1950 },new Book { Title = "Matilda", Author = "Roald Dahl", Year = 1988 },new Book { Title = "The Giving Tree", Author = "Shel Silverstein", Year = 1964 },new Book { Title = "Oh, the Places You'll Go!", Author = "Dr. Seuss", Year = 1990 }
};

您可以在 SortableList 中像下面这样呈现此列表…

<div><SortableList Items="books" Context="book"><SortableItemTemplate><div class="book"><p>@book.Title</p></div></SortableItemTemplate></SortableList>
</div>

在这里插入图片描述
SortableList 组件将使用 SortableItemTemplate 呈现项目列表,然后使用 SortableJS 使列表变得可以排序。Context 参数用于定义变量的名称,该变量将用于表示列表中的每个项目。在本例中,Context 是 book,因此列表中的每个项目都将由一个名为 book 的变量表示。

但是,如果您此时尝试拖放项目,您会发现无论您怎么拖放一个项目,它都会回到之前的位置。这是因为我们没有告诉 SortableList 在列表排序时该做什么。我们通过处理 OnUpdate 事件并自己进行排序来做到这一点。

<div><SortableList Items="books" Context="book" OnUpdate="@SortList"><SortableItemTemplate><div class="book"><p>@book.Title</p></div></SortableItemTemplate></SortableList>
</div>
...
public void SortList((int oldIndex, int newIndex) indices)
{// deconstruct the tuplevar (oldIndex, newIndex) = indices;var items = this.books;var itemToMove = items[oldIndex];items.RemoveAt(oldIndex);if (newIndex < items.Count){{items.Insert(newIndex, itemToMove);}}else{{items.Add(itemToMove);}}
}

每当列表排序时,都会调用 OnUpdate 事件处理程序。它将传递一个包含已移动项目的旧索引和新索引的元组。在 SortList 方法中,我们将元组解构为两个变量,然后使用它们来移动列表中的项目。

永远不要改变 Blazor 控制的 DOM,这一点非常重要。Blazor 保留 DOM 的内部副本,如果您使用 JavaScript 等内容更改它,您将得到奇怪的结果,因为页面状态将与 Blazor 的内部状态不同步。因此,我们在幕后所做的就是取消 JavaScript 移动,这样被移动的项目就不会真的在页面上移动。然后我们移动列表中的项目,Blazor 将按照新顺序重新渲染列表。

一个更复杂的例子

SortableJS 是一个非常强大的库,它可以做的不仅仅是排序列表。它还可以在列表之间排序、克隆项目、过滤项目等等。SortableList 组件支持许多这样的功能。让我们看一个更复杂的例子——两个列表之间的排序…

<div><div class="container"><div class="columns"><div class="column"><h3>Books</h3><SortableList Items="books" Context="book" OnRemove="@AddToFavoriteList" Group="favorites"><SortableItemTemplate><div class="book"><p>@book.Title</p></div></SortableItemTemplate></SortableList></div><div class="column"><h3>Favorite Books</h3><SortableList Items="favoriteBooks" Context="book" OnRemove="@RemoveFromFavoriteList" Group="favorites"><SortableItemTemplate><div class="book"><p>@book.Title</p></div></SortableItemTemplate></SortableList></div></div></div>
</div>

在此示例中,我们有两个列表 - 所有书籍的列表和最喜欢的书籍的列表。它们通过 Group 属性链接在一起。

我们希望能够将书籍从所有书籍列表拖放到最喜欢的书籍列表中。要做到这一点,我们需要处理两个列表的 OnRemove 事件。

public void AddToFavoriteList((int oldIndex, int newIndex) indices)
{var (oldIndex, newIndex) = indices;var book = books[oldIndex];favoriteBooks.Insert(newIndex, book);books.RemoveAt(oldIndex);
}public void RemoveFromFavoriteList((int oldIndex, int newIndex) indices)
{var (oldIndex, newIndex) = indices;var book = favoriteBooks[oldIndex];books.Insert(newIndex, book);favoriteBooks.RemoveAt(oldIndex);
}

在这里插入图片描述

设置 SortableList 的样式

默认情况下,SortableList 包含一些默认样式,这些样式在拖动时会隐藏“ghost”元素。这将在您拖动时在项目之间产生间隙。如果没有这种样式更改,项目本身将显示为可放置拖动项目的目标。这有点奇怪,因为这意味着您拖动的项目也是您放置拖动项目的目的地。但如果这就是您想要选的样式,您可以覆盖 SortableList.razor.css 文件中的样式,或者根本不包含它。

由于 SortableList 内呈现的所有内容都呈现在 SortableItemTemplate 子项内,因此您必须使用“::deep”修饰符才能使任何更改生效。

如果您从父页面/组件(即 Index.razor.css)设置 SortableList 的样式,则必须将 SortableList 包装在容器元素中,并使用“::deep”修饰符。如果您不这样做,您的样式将不会生效,您也会因为我制作这个组件却没有这个功能而感到悲伤、困惑和生气。这是 Blazor 的问题,而不是 SortableJS 的问题。您可以在 ASP.NET Core 文档中阅读有关范围样式的更多信息。

我觉得没有人会读最后一段,很多人可能会哀号。我先说声抱歉,但其实我已经尝试过了。

为什么不使用 HTML5 拖放?

这是一个很好的问题,也是我在使用 JavaScript 解决方案之前研究过的一个问题。总而言之,原生 HTML5 对拖放的支持还不够强大,无法实现合适的排序。例如,无法对大部分拖放行为进行样式化。它看起来……很愚蠢……而且我们对此无能为力。它对跨浏览器的支持也很不稳定。有一些基本属性仅适用于 Chrome。

综上所述,SortableJS 实际上会尝试使用 HTML5 拖放,并在 iOS 等平台上退回到 JavaScript 解决方案。但是,您仍然无法控制样式,并且会出现看起来愚蠢的拖放操作。所以我在 SortableList 上关闭了 HTML5 的方式。如果您希望它重新打开,请进入 SortableList.razor.razor.js 文件并删除 forceFallback: true 属性。我可能会在某个时候将其作为一个设置。

获取 Blazor Sortable

查看 Blazor Sortable 并告诉我们您的想法!您可以用它做很多事情,包括克隆项目、禁用某些项目的排序、指定拖动手柄等等。我们还没有实现 SortableJS 的所有功能。欢迎拉取请求!😉

Blazor Sortable 是一个开源社区项目。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/664592.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

算法学习——华为机考题库1(HJ1 - HJ10)

算法学习——华为机考题库1&#xff08;HJ1 - HJ10&#xff09; HJ1 字符串最后一个单词的长度 描述 计算字符串最后一个单词的长度&#xff0c;单词以空格隔开&#xff0c;字符串长度小于5000。&#xff08;注&#xff1a;字符串末尾不以空格为结尾&#xff09; 输入描述&…

【Springcloud篇】学习笔记一(一至三章):微服务介绍、构建环境

零基础微服务架构理论入门介绍 一个基于分布式的服务架构应该含有的架构内容如下&#xff1a; 1.1SpringCloud是什么 1.2基于微服务的系统 1.3服务与之对用的技术 1.4课程目录 第一章_SpringBoot和SpringCloud版本选择 详细可见SpringCloud2020.mmap文件 1.概述 2.SpringBoo…

Java自救手册

目录 访问地址 访问地址&#xff0c;发现不通&#xff0c;无法访问&#xff1a; 网络不通一般有两种情况&#xff1a; Maven 拿Maven 拿到Maven以后 Maven单独的报红 Git git注意&#xff1a; 目录 访问地址 访问地址&#xff0c;发现不通&#xff0c;无法访问&…

2024年美国大学生数学建模竞赛(D题)湖泊水位调控|粒子群强化学习建模解析,小鹿学长带队指引全代码文章与思路

我是鹿鹿学长&#xff0c;就读于上海交通大学&#xff0c;截至目前已经帮200人完成了建模与思路的构建的处理了&#xff5e; 此篇文章是由鹿鹿学长倾心打磨&#xff0c;解决挑战&#xff0c;创造美赛建模独特思路。融合粒子群算法、深度强化学习等前沿技术&#xff0c;构建全面…

Unity C#高级特性 Partial 详细使用案例

文章目录 实例 1&#xff1a;分隔UI逻辑实例 2&#xff1a;Unity编辑器自动生成代码实例 3&#xff1a;数据模型分割实例 4&#xff1a;序列化扩展实例 5&#xff1a;多视图架构实例 6&#xff1a;Unity编辑器自定义 inspectors 在Unity中&#xff0c;部分类&#xff08;Partia…

jsp服装穿搭推荐系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 JSP 游戏网上商城系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql5.0…

Elasticsearch-内存结构

ElasticSearch的内存从大的结构可以分堆内存&#xff08;On Heap&#xff09;和堆外内存&#xff08;Off Heap&#xff09;。Off Heap部分由Lucene进行管理。On Heap部分存在可GC部分和不可GC部分&#xff0c;可GC部分通过GC回收垃圾对象&#xff0c;从而释放内存。不可GC部分不…

第九节HarmonyOS 常用基础组件22-Marquee

1、描述 跑马灯组件&#xff0c;用于滚动展示一段单行文本&#xff0c;仅当文本内容宽度超过跑马灯组件宽度时滚动。 2、接口 Marquee(value:{start:boolean, step?:number, loop?:number, fromStart?: boolean ,src:string}) 3、参数 参数名 参数类型 必填 描述 st…

qt -chart控件设计器可拖拉

qt -chart控件设计器可拖拉 一、演示效果二、安装过程三、核心程序四、程序链接 一、演示效果 二、安装过程 三、核心程序 #include <QtGui> #include <QColor>#include <cstdlib> #include <cassert> #include <numeric>#include <chartwor…

【Java程序设计】【C00232】基于Springboot的抗疫物资管理系统(有论文)

基于Springboot的抗疫物资管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的抗疫物资管理系统 用户主要分为管理员和普通用户 管理员&#xff1a; 管理员可以对后台数据进行管理、拥有最高权限、具体权限有…

【LLM KBQA】FlexKBQA:一种结合LLM的KBQA框架

前言 大语言模型&#xff08;LLMs&#xff09;在知识库问答&#xff08;KBQA&#xff09;领域的应用主要集中在包括但不限于以下几个方面&#xff1a; 直接生成答案&#xff1a;一些方法直接利用LLMs生成答案&#xff0c;而不是生成中间的程序&#xff08;如SPARQL查询&#…

算法学习——华为机考题库3(HJ21 - HJ25)

算法学习——华为机考题库3&#xff08;HJ21 - HJ30&#xff09; HJ21 简单密码 描述 现在有一种密码变换算法。 九键手机键盘上的数字与字母的对应&#xff1a; 1–1&#xff0c; abc–2, def–3, ghi–4, jkl–5, mno–6, pqrs–7, tuv–8 wxyz–9, 0–0&#xff0c;把密码…

Vue3.0(一):Vue的引入-options api-模板语法

Vue的引入方式 CDN方式进行引入 将以下 script标签引入即可 <script src"https://unpkg.com/vue3/dist/vue.global.js"></script><!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><met…

Linux下tar命令详解

tar #归档命令 格式 • Tar -参数 [args]..... 参数&#xff1a; 必选参数&#xff1a; 辅助参数&#xff1a; 额外参数&#xff1a; # 打包时排除某个文件 tar cf 文件名.tar --exclude路径/文件 路径 注&#xff1a;此处的路径前后需要保持保持一致&#xff0c;统一…

使用 IDEA 开发一个简单易用的 SDK

目录 一、什么是 SDK 二、为什么要开发 SDK 三、开发 SDK 的详细步骤 四、导入 SDK 进行测试 附&#xff1a;ConfigurationProperties 注解的介绍及使用 一、什么是 SDK 1. 定义&#xff1a;软件开发工具包 Software Development Kit 2. 用于开发特定软件或应用程序的工…

Javascript | JS如何断点测试(WebStorm)

JavaScript的断点与之前所学到的Java和python在jetbrain系列编辑器中的断点debug不太一样&#xff0c;往常我们在编写python的时候用pycharm的时候是直接断点进入debug的&#xff0c;就像下面这样 只要直接在代码中断点&#xff0c;然后运行debug功能即可 但是在WebStorm中不是…

【Tomcat与网络3】Tomcat的整体架构

目录 1.演进1&#xff1a;将连接和处理服务分开 2演进2&#xff1a;Container的演进 3 再论Tomcat的容器结构 4 Tomcat处理请求的过程 5 请求的处理过程与Pipeline-Valve管道 在前面我们介绍了Servlet的基本原理&#xff0c;本文我们结合Tomcat来分析一下如何设计一个大型…

【tensorflow 版本 keras版本】

#. 安装tensorflow and keras&#xff0c; 总是遇到版本无法匹配的问题。 安装之前先查表 https://master--floydhub-docs.netlify.app/guides/environments/ 1.先确定你的python version 2.再根据下面表&#xff0c;确定安装的tesorflow, keras

如何用gpt快速做好数据分析?

由于技术限制&#xff0c;目前InfinitePaper AI仅支持上传1份文件&#xff0c;且大小不超过10M。但是&#xff0c;在强大的代码解释器面前&#xff0c;这都是小问题。我们只需要将可能用到的文件打包成压缩文件上传即可&#xff0c;之后要求GPT直接解压就能正常完成后续需求。 …

Unity 读取指定目录所占内存大小

public static class TxxTool{#region 读取文件大小private static List<string> DirList new List<string>();public static long GetFileSize(string path){DirList new List<string>();DirList.Add(path);GetAllDirecotries(path);long fileSize 0;for…