我有以下视图,显示来自控制器的游戏相关数据。
页面最初加载时,它会到达一个索引控制器,该控制器仅列出曾经创建的所有游戏会话(共100个)。
但是,有一个输入字段,用户可以在其中输入日期,然后单击一个按钮。
单击后,此按钮会将日期和时间发送到另一个名为GamingSessionsByDate的方法。
然后GamingSessionsByDate方法返回新数据,该数据仅包含游戏会话的开始日期为用户输入的任何内容。
这是视图:
@model IEnumerable<GamingSessions.Session>
@{
ViewData["Title"] = "GamingSessionsByDate";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Gaming Sessions By Date</h2>
<input type="date" name="gameSession" id="gameSession">
<input type="Submit" id="postToController" name="postToController" Value="Find" />
@section Scripts
{
<script type="text/javascript">
$("#postToController").click(function () {
var url = '@Url.Action("GamingSessionsByDate", "GameSession")';
var inputDate = new Date('2019-01-23T15:30').toISOString();
$.ajax({
type: "POST",
url: url,
data: "startdate=" + inputDate,
success: function (data) {
console.log("data: ", data);
}
});
});
</script>
}
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.GameName)
</th>
<th>
@Html.DisplayNameFor(model => model.PlayDuration)
</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.GameName)
</td>
<td>
@Html.DisplayFor(modelItem => item.PlayDuration)
</td>
</tr>
}
</tbody>
</table>
以下是按日期返回游戏会话的控制器:
public IActionResult GamingSessionsByDate(DateTime startdate)
{
var response = GetGameSessionsList(startdate);
var r = response.Results;
return View(r);
}
顺便说一句,我已经将日期时间值硬编码到上面的AJAX调用中,我知道它包含5个游戏会话。
请注意,我正在用AJAX成功方法写出从控制器返回的数据。
因此,当我单击该按钮时,屏幕上什么都没有发生,我只看到最初从呼叫到索引控制器的100个游戏会话。
但是,在后台,我可以通过Ajax调用中的console.log命令看到需要写入控制台的5个游戏会话。
在Visual Studio中逐步浏览项目时,我还会看到正确的数据。
因此,看起来一切正常,但似乎没有刷新视图/页面。
那么,如何获取该数据以显示在页面上?
谢谢!
答案 0 :(得分:2)
JavaScript中的XMLHttpRequest
对象(实际上发出“ AJAX”请求)就是所谓的“瘦客户端”。您的网络浏览器是一个“厚客户端”,它不仅执行请求并接收响应:它实际上会自动执行诸如返回的HTML,CSS和JavaScript之类的事情,并“运行”它们,构建DOM并渲染漂亮的图片。并在屏幕上显示文字。相反,瘦客户端实际上只是发出请求并接收响应。而已。它本身不会做任何事情。作为开发人员,您有责任使用响应来实际执行操作。
在这种情况下,这意味着获取您收到的响应,并操纵DOM将游戏会话列表替换为检索到的不同游戏会话。如何执行取决于您要从AJAX调用返回的确切信息。它可以是准备插入的HTML格式,也可以是诸如JSON之类的对象。在前一种情况下,您只需从DOM中选择一些父元素,然后用收到的响应替换其innerHTML。在后一种情况下,您需要使用JSON数据来实际构建元素并将元素插入DOM。
返回纯HTML更容易,但灵活性也较低。返回JSON给您最大的自由,但是开箱即用来操作DOM以显示该数据更加困难。通常就是要使用Vue,Angular,React等客户端框架的地方。所有这些都可以创建模板化组件。这样,您只需要更改基础数据源(即,将数据设置为返回的JSON),组件就会做出相应的反应,并根据需要操纵DOM来创建视图。
我个人喜欢使用Vue,因为它起步时摩擦最小,使用起来几乎非常愚蠢。例如:
<div id="App">
<input type="date" v-model="startDate" />
<button type="button" v-on:click="filterGameSessionsByDate">Find</button>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.GameName)
</th>
<th>
@Html.DisplayNameFor(model => model.PlayDuration)
</th>
</tr>
</thead>
<tbody>
<tr v-for="item in items">
<td>{{ item.GameName }}</td>
<td>{{ item.PlayDuration }}</td>
</tr>
</tbody>
</table>
</div>
然后用一些JS进行连接:
(function (options) {
let vm = new Vue({
el: '#App",
data: {
items: options.items,
startDate: null
},
methods: {
filterGameSessionsByDate: function () {
let self = this;
$.ajax({
type: "POST",
url: options.filterByDateUrl,
data: "startdate=" + self.startDate,
success: function (data) {
self.items = data;
}
});
}
}
});
})(
@Html.Raw(Json.Encode(new {
items = Model,
filterByDateUrl = Url.Action("GamingSessionsByDate", "GameSession")
}))
)
如果您不习惯使用JS,那可能看起来有点时髦。我在这里仅使用所谓的闭包:就地定义和调用函数。它需要一个options
参数,该参数由底部的括号填充。在这些内部,我正在创建一个匿名对象,其中包含我需要的信息,例如要显示的初始项以及要从中获得过滤结果的URL。然后,将该对象编码为JSON并转储到页面中。