如何使这个书架网格具有drag/select个特征?
How to make this book shelf grid have drag/select features?
简介
我正在写一个玩具项目作为概念证明并推动自己。该应用程序是一个 ASP.NET5 MVC6 库用户界面。我想创建一个具有动态属性的图书馆书架的网格表示,但是 过去两周我完全被困在这个问题上。整个事情都是开源的,你可以找到我到目前为止所做的事情 here.
问题
我希望用户能够将他们的手指拖过我的网格到 select 他们想要的任何地方。然后他们可以通过相同的手势取消select。这个想法是 "check out" 本书这样做。我一直在思考如何实现我的 M3
换句话说,如何使我创建的 DOM 对象具有交互性?
考虑下图。我有 5 个模拟场景。
M1
最基本的情况。我点击架子,我可以看到 3 x 5 架子的表示。
M2
红色代表书架上的占用位置。我想使用数据库来获取此信息以及如何向用户显示这些信息。
M3
绿色代表用户想要什么select。我假设这将在平板电脑上。所以我希望他们能够在屏幕上拖动他们的身影。
M4这是针对目前不重要的场景(检查所有内容)
M5这意味着用户可以去到不同的书架,得到不同的格子。这个书架是 3 x 5。
完成
M1到此结束。
M5到此结束。这是因为我在我的数据库中为货架指定了行和列:
所以我可以把grid画成这样:
<div class="grid">
@{ int columnN = Model.columnNumber;}
@{ int rowN = Model.rowNumber;}
@{ int container = 1;}
<div class="btn-group btn-group-justified" role="group">
<!--Select All Button-->
<button id="toggle-well-all" type="button" class="btn btn-info"><i class="fa fa-table"></i></button>
@for (int i = 1; i <= columnN; i++)
{
<!--Column Header-->
<button id="toggle-well-column-@i" type="button" class="btn btn-info">@i.ToString()</button>
}
</div>
@{int a = 0;
<!--Define the row based on Bin row size -->
for (int j = 1; j <= rowN; j++)
{
<!--Define the row header button -->
<div class="btn-group btn-group-justified" role="group">
<!--Row Header-->
<button id="toggle-well-row-@j" type="button" class="btn btn-info">@j.ToString()</button>
<!--Well Column-->
@for (int k = 1; k <= columnN; k++)
{
<!--Well Button-->
<button type="button" id="select-well-@container" class="btn btn-default bin-well bin-row-@j bin-col-@k" data-toggle="button"></button>
container++;
}
</div>
}
}
</div>
备注
为了让它尽可能干净,我正在尝试采用以下方法:
- 使用 C# 和 Razor 创建 DOM 来代表我的书架
- 用什么?使这个 DOM 具有我需要的交互功能
- 有了交互功能后,我打算将它绑定到数据库吗?
- 学习javascript
尝试次数
- 先用 javascript 做。馊主意。我无法让 javascript 读取我的 Razor 和 C# 代码。另外,不是最佳实践。所以我现在先接近它DOM。
如有任何帮助,我们将不胜感激。我愿意倾听和学习。我在这方面做了很多工作但失败了很多,所以作为最后的努力伸出援手。非常感谢您的阅读。
这是一个相当大的问题。您实质上是在询问如何构建 Web 应用程序的完整堆栈。没有一个答案可以为您解决。因此,我将告诉您我将如何更详细地解决该问题。
首先,我们需要将问题分解成更简单的事情,一次解决一个问题。由于您使用的是 MVC,因此我假设使用模型视图控制器设计模式。
考虑到这一点,我将从 C# 中的模型开始。我们至少需要一个 Book 和一个 Shelf 类型。 Book 类型的可用性为 属性。书架将有一组书籍,可能还有一个描述书架配置(即 3x5、5x7)的类型 属性。
创建模型后,我将创建一个代表我的数据访问层的假商店。这家商店会有一些书架,里面有各种配置的各种书籍。
然后我会使用假商店来处理我的 razor 视图,以简单地将货架呈现为 table。我个人会使用 css classes 来标记图书在 table 中的状态,并使用数据属性来标识图书。继续在这里工作,直到您可以将每个可能的货架配置渲染为具有适当 css classes 的 table。
最终结果 table 可能如下所示:
<table id="shelf">
<tr>
<td class="book available" data-id="1">Fight Club</td>
<td class="book checkedout" data-id="2">The Great and Secret Show</td>
</tr>
<tr>
<td class="book available" data-id="3">The Winds of Winter</td>
<td class="book checkedout" data-id="4">Ready Player One</td>
</tr>
</table>
接下来,我将开始在客户端工作 javascript 以检测用户交互事件。也许从所有将图书 ID 写入浏览器控制台的图书的触摸事件开始。然后优化您的事件订阅,以便您可以区分图书的状态。
这是一个 jQuery 的例子,以防我的意思不清楚。您可能会从一些如下所示的客户端脚本开始:
$(function() {
$("#shelf .book").on("touch", function() {
var id = $(this).data("id");
console.log(id);
});
});
然后为了区分一本书的状态,你可能会这样做:
$(function() {
$("#shelf .book").on("touch", ".available", function() {
var id = $(this).data("id");
console.log(id + " available");
});
$("#shelf .book").on("touch", ".checkedout", function () {
var id = $(this).data("id");
console.log(id + " checkedout");
});
});
注意:上面的代码我没有测试。所以考虑它可能需要一些调整的伪代码。
现在您已经有了获取图书 ID 的触摸事件的事件处理程序,我将编写一个 ajax 调用 post 控制器操作的 ID,具体到我要执行的操作.所以对于可用的书籍,我会 post 到 /books/checkout/id 之类的东西。对于借出的图书,post 到 books/checkin/id。我会去掉 bookscontroller 的操作方法以简单地 return 一个积极的回应。
在我的 ajax 调用成功事件中,我会适当地交换 css class。例如,一本可用的书将 post ajax 调用 /books/checkout/id,成功后我将删除可用的 class 并添加已签出的 class.
接下来,我会努力让我的假商店真正将数据存储在数据库中。
然后,连接我的书籍控制器操作存根以修改数据库中的数据。
最后,考虑错误情况。如果我 post 已签出的结帐操作的图书 ID 会怎样?如果具有该 ID 的书不存在怎么办?如果我签出一本书,查看该书架的其他人如何知道它已签出?
如您所见,我正在解决将其分解成小块的问题。实施小事,成就大事。我在后端、控制器、客户端的各个层之间跳来跳去 ui 存根,并最终根据需要替换为新代码。
但这还不是全部!最后考虑您拥有的代码的质量。尝试删除任何重复项(尤其是重复 3 次或更多次时)。查看所有变量、classes 和方法的名称,它们是否准确地表示正在发生的事情?请记住变量、class 和方法名称可以任意长,使它们具有描述性。 "var x" 或 "var bookId" 哪个更有意义?
基本上我所说的是为了简洁明了而重构。当您回来尝试编辑此代码时,您 6 个月大的自己会感谢您。
不要让我开始单元测试....
祝你好运。
简介
我正在写一个玩具项目作为概念证明并推动自己。该应用程序是一个 ASP.NET5 MVC6 库用户界面。我想创建一个具有动态属性的图书馆书架的网格表示,但是 过去两周我完全被困在这个问题上。整个事情都是开源的,你可以找到我到目前为止所做的事情 here.
问题
我希望用户能够将他们的手指拖过我的网格到 select 他们想要的任何地方。然后他们可以通过相同的手势取消select。这个想法是 "check out" 本书这样做。我一直在思考如何实现我的 M3
换句话说,如何使我创建的 DOM 对象具有交互性?
考虑下图。我有 5 个模拟场景。
M1 最基本的情况。我点击架子,我可以看到 3 x 5 架子的表示。
M2 红色代表书架上的占用位置。我想使用数据库来获取此信息以及如何向用户显示这些信息。
M3 绿色代表用户想要什么select。我假设这将在平板电脑上。所以我希望他们能够在屏幕上拖动他们的身影。
M4这是针对目前不重要的场景(检查所有内容)
M5这意味着用户可以去到不同的书架,得到不同的格子。这个书架是 3 x 5。
完成
M1到此结束。
M5到此结束。这是因为我在我的数据库中为货架指定了行和列:
所以我可以把grid画成这样:
<div class="grid">
@{ int columnN = Model.columnNumber;}
@{ int rowN = Model.rowNumber;}
@{ int container = 1;}
<div class="btn-group btn-group-justified" role="group">
<!--Select All Button-->
<button id="toggle-well-all" type="button" class="btn btn-info"><i class="fa fa-table"></i></button>
@for (int i = 1; i <= columnN; i++)
{
<!--Column Header-->
<button id="toggle-well-column-@i" type="button" class="btn btn-info">@i.ToString()</button>
}
</div>
@{int a = 0;
<!--Define the row based on Bin row size -->
for (int j = 1; j <= rowN; j++)
{
<!--Define the row header button -->
<div class="btn-group btn-group-justified" role="group">
<!--Row Header-->
<button id="toggle-well-row-@j" type="button" class="btn btn-info">@j.ToString()</button>
<!--Well Column-->
@for (int k = 1; k <= columnN; k++)
{
<!--Well Button-->
<button type="button" id="select-well-@container" class="btn btn-default bin-well bin-row-@j bin-col-@k" data-toggle="button"></button>
container++;
}
</div>
}
}
</div>
备注
为了让它尽可能干净,我正在尝试采用以下方法:
- 使用 C# 和 Razor 创建 DOM 来代表我的书架
- 用什么?使这个 DOM 具有我需要的交互功能
- 有了交互功能后,我打算将它绑定到数据库吗?
- 学习javascript
尝试次数
- 先用 javascript 做。馊主意。我无法让 javascript 读取我的 Razor 和 C# 代码。另外,不是最佳实践。所以我现在先接近它DOM。
如有任何帮助,我们将不胜感激。我愿意倾听和学习。我在这方面做了很多工作但失败了很多,所以作为最后的努力伸出援手。非常感谢您的阅读。
这是一个相当大的问题。您实质上是在询问如何构建 Web 应用程序的完整堆栈。没有一个答案可以为您解决。因此,我将告诉您我将如何更详细地解决该问题。
首先,我们需要将问题分解成更简单的事情,一次解决一个问题。由于您使用的是 MVC,因此我假设使用模型视图控制器设计模式。
考虑到这一点,我将从 C# 中的模型开始。我们至少需要一个 Book 和一个 Shelf 类型。 Book 类型的可用性为 属性。书架将有一组书籍,可能还有一个描述书架配置(即 3x5、5x7)的类型 属性。
创建模型后,我将创建一个代表我的数据访问层的假商店。这家商店会有一些书架,里面有各种配置的各种书籍。
然后我会使用假商店来处理我的 razor 视图,以简单地将货架呈现为 table。我个人会使用 css classes 来标记图书在 table 中的状态,并使用数据属性来标识图书。继续在这里工作,直到您可以将每个可能的货架配置渲染为具有适当 css classes 的 table。
最终结果 table 可能如下所示:
<table id="shelf">
<tr>
<td class="book available" data-id="1">Fight Club</td>
<td class="book checkedout" data-id="2">The Great and Secret Show</td>
</tr>
<tr>
<td class="book available" data-id="3">The Winds of Winter</td>
<td class="book checkedout" data-id="4">Ready Player One</td>
</tr>
</table>
接下来,我将开始在客户端工作 javascript 以检测用户交互事件。也许从所有将图书 ID 写入浏览器控制台的图书的触摸事件开始。然后优化您的事件订阅,以便您可以区分图书的状态。
这是一个 jQuery 的例子,以防我的意思不清楚。您可能会从一些如下所示的客户端脚本开始:
$(function() {
$("#shelf .book").on("touch", function() {
var id = $(this).data("id");
console.log(id);
});
});
然后为了区分一本书的状态,你可能会这样做:
$(function() {
$("#shelf .book").on("touch", ".available", function() {
var id = $(this).data("id");
console.log(id + " available");
});
$("#shelf .book").on("touch", ".checkedout", function () {
var id = $(this).data("id");
console.log(id + " checkedout");
});
});
注意:上面的代码我没有测试。所以考虑它可能需要一些调整的伪代码。
现在您已经有了获取图书 ID 的触摸事件的事件处理程序,我将编写一个 ajax 调用 post 控制器操作的 ID,具体到我要执行的操作.所以对于可用的书籍,我会 post 到 /books/checkout/id 之类的东西。对于借出的图书,post 到 books/checkin/id。我会去掉 bookscontroller 的操作方法以简单地 return 一个积极的回应。
在我的 ajax 调用成功事件中,我会适当地交换 css class。例如,一本可用的书将 post ajax 调用 /books/checkout/id,成功后我将删除可用的 class 并添加已签出的 class.
接下来,我会努力让我的假商店真正将数据存储在数据库中。
然后,连接我的书籍控制器操作存根以修改数据库中的数据。
最后,考虑错误情况。如果我 post 已签出的结帐操作的图书 ID 会怎样?如果具有该 ID 的书不存在怎么办?如果我签出一本书,查看该书架的其他人如何知道它已签出?
如您所见,我正在解决将其分解成小块的问题。实施小事,成就大事。我在后端、控制器、客户端的各个层之间跳来跳去 ui 存根,并最终根据需要替换为新代码。
但这还不是全部!最后考虑您拥有的代码的质量。尝试删除任何重复项(尤其是重复 3 次或更多次时)。查看所有变量、classes 和方法的名称,它们是否准确地表示正在发生的事情?请记住变量、class 和方法名称可以任意长,使它们具有描述性。 "var x" 或 "var bookId" 哪个更有意义?
基本上我所说的是为了简洁明了而重构。当您回来尝试编辑此代码时,您 6 个月大的自己会感谢您。
不要让我开始单元测试....
祝你好运。