如何在 PageModel(通过按钮)中为表单分配 属性,维护选定的页面布局 [ASP.NET/Razor 页面]
How to assign property in PageModel (by button) for form, maintaining selected page layout [ASP.NET/Razor Page]
我的项目有管理盔甲的页面。到目前为止,页面允许用户从数据库中显示 table,创建新装甲并删除。不幸的是,我无法实施 editing/updating。
当用户第一次打开页面时,看到的是带有项目的 table,每个项目都有 2 个按钮(编辑和删除)。在 table 上方放置按钮,使包含 table 的 DIV 消失并显示包含 DIV 的表单。编辑按钮做同样的事情。这是由 JavaScript 处理的。
我想用同样的形式来更新盔甲。但要做到这一点,首先需要将选定的盔甲分配给 PageModel 中的 Armor 属性。到目前为止,我能够使用 IActionResult OnPost 方法来完成它,但是页面随后重新加载,我所有的努力都白费了。当我尝试 return Page() 然后我的页面被重新加载为空 table,如果我使用 RedirectToPage(“PageName”) 那么我仍然会丢失选定的项目并且默认情况下显示 table , 而不是带有选定装甲数据的表格。我该怎么做?不使用额外的 JavaScript 但 OnPost metod/s 是可能的吗?如果没有,我可以改变什么以及如何改变?
我正在使用 asp.net 核心 3.1、Entity Framework 和 Razor Pages。
GitHub: https://github.com/Mlorism/LastTemple/tree/master/LastTemple/Pages/Manage
CSHTML:
<div class="col-7 pl-5 pr-5">
<div id="armourTable" class="text-center">
<button class="btn btn-outline-light mb-2" onclick="ToggleColumn(1)">Stwórz pancerz</button>
<table class="table text-light text-center">
<thead>
<tr>
<th scope="col">Id</th>
<th scope="col">Nazwa</th>
<th scope="col">Odp. fiz.</th>
<th scope="col">Odp. mag.</th>
<th scope="col"></th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.Armors)
{
<tr id="tr-@item.Id">
<th scope="row">@item.Id</th>
<td>@item.Name</td>
<td>@item.DamageResistance</td>
<td>@item.MagicResistance</td>
<td><form method="post"><button class="btn btn-outline-warning" type="submit" onclick="Edit(@item.Id)" asp-page-handler="LoadArmor" asp-route-id="@item.Id">Edytuj</button></form></td>
<td><form method="post"><button class="btn btn-outline-warning" type="submit" asp-page-handler="Delete" asp-route-id="@item.Id">Usuń</button></form></td>
</tr>
}
</tbody>
</table>
</div>
<div id="armourForm" class="p-5">
<form id="manipulateArmor" method="post" onreset="resetSliders()">
<div class="form-group">
<label>Nazwa</label>
<input type="text" class="form-control bg-secondary text-light" minlength="5" maxlength="20" required="required" asp-for="Armor.Name" />
<small>Długość od 5 do 20 znaków</small>
</div>
<div class="form-group">
<label>Odporność na obrażenia</label>
<input id="physical" class="mySlider" type="range" value="10" min="0" max="100" step="5" asp-for="Armor.DamageResistance" />
<output>10</output>
</div>
<div class="form-text">
<label>Odporność na magię</label>
<input id="magic" class="mySlider" type="range" value="10" min="0" max="50" step="5" asp-for="Armor.MagicResistance" />
<output>10</output>
</div>
<div class="text-center">
<button type="submit" asp-page-handler="Create" class="btn btn-outline-success m-2">Zapisz</button>
<button id="resetBtn" type="reset" class="btn btn-outline-warning m-2">Resetuj</button>
<button type="button" class="btn btn-outline-danger m-2" onclick="ToggleColumn(0)">Anuluj</button>
</div>
</form>
</div>
</div>
页面模型 cs:
private readonly ApplicationDbContext _ctx;
public ArmourModel(ApplicationDbContext ctx)
{
_ctx = ctx;
}
[BindProperty]
public Armor Armor { get; set; }
[BindProperty]
public IEnumerable<Armor> Armors { get; set; }
public void OnGet()
{
Armors = new GetArmors(_ctx).Get();
}
public async Task<IActionResult> OnPostCreateAsync()
{
await new CreateArmor(_ctx).Create(Armor);
return RedirectToPage("Armor");
}
public IActionResult OnPostLoadArmor(int id)
{
Armor item = _ctx.Armors.Find(id);
if (item == null)
{
RedirectToPage("Armor");
}
Armor.Id = item.Id;
Armor.Name = item.Name;
Armor.DamageResistance = item.DamageResistance;
Armor.MagicResistance = item.MagicResistance;
return RedirectToPage("Armor");
}
JS:
function ToggleColumn(type) {
var armourTable = document.getElementById("armourTable");
var armourForm = document.getElementById("armourForm");
var resetBtn = document.getElementById("resetBtn");
if (type == 0) {
armourTable.style.display = "block";
armourForm.style.display = "none";
resetBtn.style.display = "inline-block";
}
else {
armourForm.style.display = "block";
armourTable.style.display = "none";
setSlider("physical");
setSlider("magic");
if (type == 2) {
resetBtn.style.display = "none";
}
}
} // ToggleColumn()
我修改了它,还添加了一些js代码来实现你的需求,你可以参考下面的代码:
Armor.cshtml
@page
@model LastTemple.Pages.Create.ArmourModel
@{ }
<p class="text-center font-weight-bold mb-2">Zarządzaj pancerzami</p>
<div class="row">
<div class="col-5 p-1">
<img src="~/img/armor.png" class="img-thumbnail-dark" />
</div>
<div class="col-7 pl-5 pr-5">
<div id="armourTable" class="text-center">
<button class="btn btn-outline-light mb-2" onclick="ToggleColumn(1)">Stwórz pancerz</button>
<table class="table text-light text-center">
<thead>
<tr>
<th scope="col">Id</th>
<th scope="col">Nazwa</th>
<th scope="col">Odp. fiz.</th>
<th scope="col">Odp. mag.</th>
<th scope="col"></th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.Armors)
{
<tr id="tr-@item.Id">
<th scope="row">@item.Id</th>
<td>@item.Name</td>
<td>@item.DamageResistance</td>
<td>@item.MagicResistance</td>
<td><button class="btn btn-outline-warning" name="edit" type="submit" onclick="ToggleColumn(2)">Edytuj</button></td>
<td><form method="post"><button class="btn btn-outline-warning" type="submit" asp-page-handler="Delete" asp-route-id="@item.Id">Usuń</button></form></td>
</tr>
}
</tbody>
</table>
</div>
<div id="armourForm" style="display:none" class="p-5">
<form id="manipulateArmor" method="post" onreset="resetSliders()">
<input type="hidden" id="id" asp-for="Armor.Id" />
<div class="form-group">
<label>Nazwa</label>
<input type="text" id="nazwa" class="form-control bg-secondary text-light" minlength="5" maxlength="20" required="required" asp-for="Armor.Name" />
<small>Długość od 5 do 20 znaków</small>
</div>
<div class="form-group">
<label>Odporność na obrażenia</label>
<input id="physical" class="mySlider" type="range" value="10" min="0" max="100" step="5" asp-for="Armor.DamageResistance" />
<output>10</output>
</div>
<div class="form-text">
<label>Odporność na magię</label>
<input id="magic" class="mySlider" type="range" value="10" min="0" max="50" step="5" asp-for="Armor.MagicResistance" />
<output>10</output>
</div>
<div class="text-center">
<button id="createBtn" type="submit" asp-page-handler="Create" class="btn btn-outline-success m-2">Zapisz</button>
<button id="editBtn" type="submit" asp-page-handler="Update" class="btn btn-outline-success m-2">Edytować</button>
<button id="resetBtn" type="reset" class="btn btn-outline-warning m-2">Resetuj</button>
<button type="button" class="btn btn-outline-danger m-2" onclick="ToggleColumn(0)">Anuluj</button>
</div>
</form>
</div>
</div>
@section scripts{
<script type="text/javascript">
var form = document.getElementById("manipulateArmor");
loadSettings();
document.getElementById("physical").oninput = function () { setSlider("physical"); }
document.getElementById("magic").oninput = function () { setSlider("magic"); }
function loadSettings() {
setSlider("physical");
setSlider("magic");
ToggleColumn(0);
}
function resetSliders() {
window.requestAnimationFrame(function (timestamp) {
setSlider("physical");
setSlider("magic");
})
}
function setSlider(type) {
var slider = document.getElementById(type)
var value = (slider.value - slider.min) / (slider.max - slider.min) * 100
if (slider == null) {
alert("slider is null");
}
if (type == "physical") {
slider.style.background = 'linear-gradient(to right, #FF6B6B 0%, #FF0000 ' + value + '%, #000 ' + value + '%, black 100%)'
}
else {
slider.style.background = 'linear-gradient(to right, #0000FF 0%, #6600CC ' + value + '%, #000 ' + value + '%, black 100%)'
}
slider.nextElementSibling.value = slider.value
};
function ToggleColumn(type) {
var armourTable = document.getElementById("armourTable");
var armourForm = document.getElementById("armourForm");
var resetBtn = document.getElementById("resetBtn");
var createBtn = document.getElementById("createBtn");
var editBtn = document.getElementById("editBtn");
if (type == 0) {
armourTable.style.display = "block";
armourForm.style.display = "none";
editBtn.style.display = "none";
resetBtn.style.display = "inline-block";
}
else {
armourForm.style.display = "block";
armourTable.style.display = "none";
setSlider("physical");
setSlider("magic");
if (type == 2) {
var x = event.srcElement.parentElement.parentElement;
var id = x.children[0].innerHTML;
var name = x.children[1].innerHTML;
$("#id").val(id);
$("#nazwa").val(name);
editBtn.style.display ="inline-block"
resetBtn.style.display = "none";
createBtn.style.display = "none";
} else {
editBtn.style.display = "none";
resetBtn.style.display = "inline-block";
createBtn.style.display = "inline-block";
}
}
}
</script>
}
</div>
更新函数:
public async Task<IActionResult> OnPostUpdateAsync()
{
var target = _ctx.Armors.Find(Armor.Id);
if (target == null)
{
return RedirectToPage("Armor");
}
target.Name = Armor.Name;
target.DamageResistance = Armor.DamageResistance;
target.MagicResistance = Armor.MagicResistance;
await _ctx.SaveChangesAsync();
return RedirectToPage("Armor");
}
结果:
我的项目有管理盔甲的页面。到目前为止,页面允许用户从数据库中显示 table,创建新装甲并删除。不幸的是,我无法实施 editing/updating。
当用户第一次打开页面时,看到的是带有项目的 table,每个项目都有 2 个按钮(编辑和删除)。在 table 上方放置按钮,使包含 table 的 DIV 消失并显示包含 DIV 的表单。编辑按钮做同样的事情。这是由 JavaScript 处理的。
我想用同样的形式来更新盔甲。但要做到这一点,首先需要将选定的盔甲分配给 PageModel 中的 Armor 属性。到目前为止,我能够使用 IActionResult OnPost 方法来完成它,但是页面随后重新加载,我所有的努力都白费了。当我尝试 return Page() 然后我的页面被重新加载为空 table,如果我使用 RedirectToPage(“PageName”) 那么我仍然会丢失选定的项目并且默认情况下显示 table , 而不是带有选定装甲数据的表格。我该怎么做?不使用额外的 JavaScript 但 OnPost metod/s 是可能的吗?如果没有,我可以改变什么以及如何改变?
我正在使用 asp.net 核心 3.1、Entity Framework 和 Razor Pages。
GitHub: https://github.com/Mlorism/LastTemple/tree/master/LastTemple/Pages/Manage
CSHTML:
<div class="col-7 pl-5 pr-5">
<div id="armourTable" class="text-center">
<button class="btn btn-outline-light mb-2" onclick="ToggleColumn(1)">Stwórz pancerz</button>
<table class="table text-light text-center">
<thead>
<tr>
<th scope="col">Id</th>
<th scope="col">Nazwa</th>
<th scope="col">Odp. fiz.</th>
<th scope="col">Odp. mag.</th>
<th scope="col"></th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.Armors)
{
<tr id="tr-@item.Id">
<th scope="row">@item.Id</th>
<td>@item.Name</td>
<td>@item.DamageResistance</td>
<td>@item.MagicResistance</td>
<td><form method="post"><button class="btn btn-outline-warning" type="submit" onclick="Edit(@item.Id)" asp-page-handler="LoadArmor" asp-route-id="@item.Id">Edytuj</button></form></td>
<td><form method="post"><button class="btn btn-outline-warning" type="submit" asp-page-handler="Delete" asp-route-id="@item.Id">Usuń</button></form></td>
</tr>
}
</tbody>
</table>
</div>
<div id="armourForm" class="p-5">
<form id="manipulateArmor" method="post" onreset="resetSliders()">
<div class="form-group">
<label>Nazwa</label>
<input type="text" class="form-control bg-secondary text-light" minlength="5" maxlength="20" required="required" asp-for="Armor.Name" />
<small>Długość od 5 do 20 znaków</small>
</div>
<div class="form-group">
<label>Odporność na obrażenia</label>
<input id="physical" class="mySlider" type="range" value="10" min="0" max="100" step="5" asp-for="Armor.DamageResistance" />
<output>10</output>
</div>
<div class="form-text">
<label>Odporność na magię</label>
<input id="magic" class="mySlider" type="range" value="10" min="0" max="50" step="5" asp-for="Armor.MagicResistance" />
<output>10</output>
</div>
<div class="text-center">
<button type="submit" asp-page-handler="Create" class="btn btn-outline-success m-2">Zapisz</button>
<button id="resetBtn" type="reset" class="btn btn-outline-warning m-2">Resetuj</button>
<button type="button" class="btn btn-outline-danger m-2" onclick="ToggleColumn(0)">Anuluj</button>
</div>
</form>
</div>
</div>
页面模型 cs:
private readonly ApplicationDbContext _ctx;
public ArmourModel(ApplicationDbContext ctx)
{
_ctx = ctx;
}
[BindProperty]
public Armor Armor { get; set; }
[BindProperty]
public IEnumerable<Armor> Armors { get; set; }
public void OnGet()
{
Armors = new GetArmors(_ctx).Get();
}
public async Task<IActionResult> OnPostCreateAsync()
{
await new CreateArmor(_ctx).Create(Armor);
return RedirectToPage("Armor");
}
public IActionResult OnPostLoadArmor(int id)
{
Armor item = _ctx.Armors.Find(id);
if (item == null)
{
RedirectToPage("Armor");
}
Armor.Id = item.Id;
Armor.Name = item.Name;
Armor.DamageResistance = item.DamageResistance;
Armor.MagicResistance = item.MagicResistance;
return RedirectToPage("Armor");
}
JS:
function ToggleColumn(type) {
var armourTable = document.getElementById("armourTable");
var armourForm = document.getElementById("armourForm");
var resetBtn = document.getElementById("resetBtn");
if (type == 0) {
armourTable.style.display = "block";
armourForm.style.display = "none";
resetBtn.style.display = "inline-block";
}
else {
armourForm.style.display = "block";
armourTable.style.display = "none";
setSlider("physical");
setSlider("magic");
if (type == 2) {
resetBtn.style.display = "none";
}
}
} // ToggleColumn()
我修改了它,还添加了一些js代码来实现你的需求,你可以参考下面的代码:
Armor.cshtml
@page
@model LastTemple.Pages.Create.ArmourModel
@{ }
<p class="text-center font-weight-bold mb-2">Zarządzaj pancerzami</p>
<div class="row">
<div class="col-5 p-1">
<img src="~/img/armor.png" class="img-thumbnail-dark" />
</div>
<div class="col-7 pl-5 pr-5">
<div id="armourTable" class="text-center">
<button class="btn btn-outline-light mb-2" onclick="ToggleColumn(1)">Stwórz pancerz</button>
<table class="table text-light text-center">
<thead>
<tr>
<th scope="col">Id</th>
<th scope="col">Nazwa</th>
<th scope="col">Odp. fiz.</th>
<th scope="col">Odp. mag.</th>
<th scope="col"></th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.Armors)
{
<tr id="tr-@item.Id">
<th scope="row">@item.Id</th>
<td>@item.Name</td>
<td>@item.DamageResistance</td>
<td>@item.MagicResistance</td>
<td><button class="btn btn-outline-warning" name="edit" type="submit" onclick="ToggleColumn(2)">Edytuj</button></td>
<td><form method="post"><button class="btn btn-outline-warning" type="submit" asp-page-handler="Delete" asp-route-id="@item.Id">Usuń</button></form></td>
</tr>
}
</tbody>
</table>
</div>
<div id="armourForm" style="display:none" class="p-5">
<form id="manipulateArmor" method="post" onreset="resetSliders()">
<input type="hidden" id="id" asp-for="Armor.Id" />
<div class="form-group">
<label>Nazwa</label>
<input type="text" id="nazwa" class="form-control bg-secondary text-light" minlength="5" maxlength="20" required="required" asp-for="Armor.Name" />
<small>Długość od 5 do 20 znaków</small>
</div>
<div class="form-group">
<label>Odporność na obrażenia</label>
<input id="physical" class="mySlider" type="range" value="10" min="0" max="100" step="5" asp-for="Armor.DamageResistance" />
<output>10</output>
</div>
<div class="form-text">
<label>Odporność na magię</label>
<input id="magic" class="mySlider" type="range" value="10" min="0" max="50" step="5" asp-for="Armor.MagicResistance" />
<output>10</output>
</div>
<div class="text-center">
<button id="createBtn" type="submit" asp-page-handler="Create" class="btn btn-outline-success m-2">Zapisz</button>
<button id="editBtn" type="submit" asp-page-handler="Update" class="btn btn-outline-success m-2">Edytować</button>
<button id="resetBtn" type="reset" class="btn btn-outline-warning m-2">Resetuj</button>
<button type="button" class="btn btn-outline-danger m-2" onclick="ToggleColumn(0)">Anuluj</button>
</div>
</form>
</div>
</div>
@section scripts{
<script type="text/javascript">
var form = document.getElementById("manipulateArmor");
loadSettings();
document.getElementById("physical").oninput = function () { setSlider("physical"); }
document.getElementById("magic").oninput = function () { setSlider("magic"); }
function loadSettings() {
setSlider("physical");
setSlider("magic");
ToggleColumn(0);
}
function resetSliders() {
window.requestAnimationFrame(function (timestamp) {
setSlider("physical");
setSlider("magic");
})
}
function setSlider(type) {
var slider = document.getElementById(type)
var value = (slider.value - slider.min) / (slider.max - slider.min) * 100
if (slider == null) {
alert("slider is null");
}
if (type == "physical") {
slider.style.background = 'linear-gradient(to right, #FF6B6B 0%, #FF0000 ' + value + '%, #000 ' + value + '%, black 100%)'
}
else {
slider.style.background = 'linear-gradient(to right, #0000FF 0%, #6600CC ' + value + '%, #000 ' + value + '%, black 100%)'
}
slider.nextElementSibling.value = slider.value
};
function ToggleColumn(type) {
var armourTable = document.getElementById("armourTable");
var armourForm = document.getElementById("armourForm");
var resetBtn = document.getElementById("resetBtn");
var createBtn = document.getElementById("createBtn");
var editBtn = document.getElementById("editBtn");
if (type == 0) {
armourTable.style.display = "block";
armourForm.style.display = "none";
editBtn.style.display = "none";
resetBtn.style.display = "inline-block";
}
else {
armourForm.style.display = "block";
armourTable.style.display = "none";
setSlider("physical");
setSlider("magic");
if (type == 2) {
var x = event.srcElement.parentElement.parentElement;
var id = x.children[0].innerHTML;
var name = x.children[1].innerHTML;
$("#id").val(id);
$("#nazwa").val(name);
editBtn.style.display ="inline-block"
resetBtn.style.display = "none";
createBtn.style.display = "none";
} else {
editBtn.style.display = "none";
resetBtn.style.display = "inline-block";
createBtn.style.display = "inline-block";
}
}
}
</script>
}
</div>
更新函数:
public async Task<IActionResult> OnPostUpdateAsync()
{
var target = _ctx.Armors.Find(Armor.Id);
if (target == null)
{
return RedirectToPage("Armor");
}
target.Name = Armor.Name;
target.DamageResistance = Armor.DamageResistance;
target.MagicResistance = Armor.MagicResistance;
await _ctx.SaveChangesAsync();
return RedirectToPage("Armor");
}
结果: