每当用户单击第一个 table (MVC 5)中的一行时,如何在第二个 table 中动态加载相关数据?

How can I dynamically load related data in a second table whenever the user clicks on a row from the first table (MVC 5)?

我有两个 table,Students 和 类,它们通过第三个 table 链接起来,叫做 Student类。

学生

id          Name      Age    
----------------------------
1     |     John  |   31
2     |     Bob   |   22 
3     |     Alice |   18

id          ClassName   
----------------------------
1     |       Geography  
2     |       Math    
3     |       Science
4     |       Anthropology
5     |       Spanish
6     |       Literature

学生类

sid | cid
----------
1   |  1
1   |  3
1   |  4
2   |  2
2   |  4
3   |  6  

在我看来,我知道我可以访问 类 学生正在使用以下内容:

@model IEnumerable<Students>
...
...
...
<table>
@foreach (var item in Model)
{
      <tr>
         <td>item.Name</td>
         <td>item.Age</td>
      </tr>
      <tr>
         @foreach (var item2 in item.StudentClasses)
         {
            <td>item2.ClassName</td>
         }
      </tr>
}
</table>
...
...
...

使用当前的方式,(如果我的术语正确的话)每个学生的 类 都是在嵌套的 for 循环中延迟加载的。即

Table1
-----------------------------------
|John 31                        |
|Geography Science Anthropology |
|Bob 22                         |
|Math Anthropology              |
|Alice 18                       |
|Literature                     |
------------------------------------

我想做的是有一个完全独立的 table,这样当用户点击学生姓名时,它会动态地用他们的 类 填充 table .与所有 类 不同,每个学生都被列在他们学生的下方。例如,如果用户单击 John,他们将看到以下内容:

Table 1                           Table 2
---------             --------------------------------
|John 31 |            |Geography Science Anthropology |
|Bob 22  |            |                               |
|Alice 18|            |                               |
---------             ---------------------------------

如果他们点击鲍勃,他们会看到:

Table 1                           Table 2
---------             --------------------------------
|John 31 |            |Math Anthropology              |
|Bob 22  |            |                               |
|Alice 18|            |                               |
---------             ---------------------------------

我意识到我可以使用 ajax 来动态更新 table。但是,我觉得这是一种浪费……毕竟,所有必要的数据都已经发送到视图了。为什么我必须返回带有学生 ID 的服务器,搜索与学生 ID 关联的所有 类,然后将其传递回我的视图 - 当所有这些信息都是延迟加载时?

有没有一种简单的方法可以让我在一秒钟内为每个学生动态加载 类 table,并用相关的 类 更新 table学生姓名被点击?

对于 Razor,请务必注意,虽然 cshtml 文件会在客户端生成 HTML 文件,但它们是在请求加载视图期间由服务器处理的模板。

这样的陈述:

@foreach (var item in Model)

cshtml 在服务器端进行处理,最终生成 HTML,其中包含您的模型提供的数据。现在,您的模型要么急切加载,要么依靠延迟加载来为学生获取课程。如果您删除:

     @foreach (var item2 in item.StudentClasses)
     {
        <td>item2.ClassName</td>
     }  

那么生成的 HTML 只会列出没有 类 的学生,但是我们如何在客户端获得 类?

最简单的答案是当用户 select 是学生时发布表单。 Razor 页面可以接受 studentId 参数,该参数为 类 if/where 加载结果 table 一个学生 selected。这会导致每次 select 学生时 post- 返回服务器,但会产生一个非常简单的 Razor 页面,通常刷新速度非常快。它还减少了发送到客户端的“数据”的总体有效负载,但它确实会导致服务器的额外流量,在服务器上几乎所有在页面上执行的操作都可能导致 post-back。许多开发人员“poo-poo”这种方法,因为对于较大的系统,它有规模限制,但对于简单的场景来说它工作得很好。

另一个避免 post-backs 的选项是确保 类 被加载,然后给客户端页面有一个 JSON 数据副本。一种常见的方法是通过“捕获”模型的 <script> 块:

<script type="text/javascript">

    var model = @Html.Raw(Json.Encode(Model));

</script>

这最终做的是当页面被组成时,整个模型将被序列化到 JSON,并且可以访问客户端。有一些 drawbacks/considerations 采用这种方法:

  1. 数据大小。您现在将整个数据集合发送给客户端,除了为学生生成 HTML 之外,您还发送所有学生及其各自的 类.
  2. 您正在向客户公开您模型的所有内容。通过发送实体,整个实体图将被序列化并发送。这包括您不打算显示的字段和相关实体。

在这两种情况下,通常最好将您的实体投影到视图模型,以确保发送到客户端的有效负载尽可能小,并且只显示需要的内容。

从这里开始,实施将是为每个学生项目连接一个 Javascript 事件,然后从可从 Javascript 访问的序列化“模型”实例中提取关联的 类 ,为 类 构建结果 Table,然后将生成的 HTML 注入到占位符 <div> 设置中。这为您的页面增加了一些代码和复杂性,但避免了 post-back 刷新。这确实增加了处理 if/when 页面刷新的复杂性,因为它取决于客户端来跟踪 selected 学生。

第三个选项是两者的混合,使用 Ajax 调用。这里的关键是,当首先填充你的学生时,你将数据负载最小化到只是学生的详细信息,而不是课程。然后,当您单击学生时,Javascript 会向服务器发出 Ajax 调用,以检索课程的原始 JSON 数据并为课程客户端编写视图,或者它在响应中从服务器接收序列化的局部视图 (HTML)。 POST 调用可以 return PartialView 响应,但是对于 Ajax 调用,通常最好 return 一个 JSON 结果,这样您就可以提供类似success/failure/error 消息以及序列化视图。在成功的场景中,部分视图被直接送入等待占位符 <div>。这会使解决方案稍微复杂一些,但好处是您仍然可以利用 Razor 服务器端生成您的部分视图(课程列表),而不是使用 Javascript 构建它。 Thought JS 非常适合简单的视图。与第二种方法一样,这也需要实现逻辑来跟踪 selected 学生,因此如果刷新页面,服务器可以 send/render selected 课程。 Ajax 调用可以更新会话状态服务器端,而不是像表单回传那样依赖 URL 参数,这样页面 post(表单刷新等)仍然可以查询会话状态以确定如果学生 selected 并呈现结果课程列表。

构建响应迅速、可扩展的 Web 应用程序是一个相当复杂的主题,有许多不同的方法和注意事项。最终根据您所知道的需求从简单开始,然后针对您的需求搜索或解决您面临的问题。许多关于最佳实践的讨论(比如使用客户端框架等)都源于具有大量功能和数百万并发用户的大型系统所面临的需求。作为一名开发人员,您可能会因为担心这些问题而陷入困境。 :) 对所有建议(包括我的)持保留态度,并始终将 YAGNI(你不会需要它)放在调查的最前沿。

如果您对 Ajax 方法/w 局部视图感兴趣,这是一个很好的起点:

https://www.codeproject.com/Articles/216439/Data-Validation-Using-Annotations-for-jQuery-Ajax