这篇主要整合以下几点来实作
方便之後与轻前端 Vue 的版本做个比较 !
延续前一次的范例
後端变更
public class ViewModel
{
// ...
[Display(Name = "小计")]
public decimal? SubTotalAmount { get; set; }
[Display(Name = "税金")]
public decimal? Tax { get; set; }
[Display(Name = "总计")]
public decimal? TotalAmount { get; set; }
}
public class OrderItem
{
// ...
/// <summary>
/// 单价
/// </summary>
[Display(Name = "单价")]
public decimal? UnitPrice { get; set; }
// ...
/// <summary>
/// 金额
/// </summary>
[Display(Name = "金额")]
public decimal? Amount { get; set; }
}
Contoller 新增计算功能 Action
[HttpPost, Route("api/[controller]/[action]")]
[ValidateAntiForgeryToken]
public IActionResult Calculate([FromForm]ViewModel vm)
{
if (vm?.Items?.Length > 0 == false)
{
return Ok(vm);
}
vm.SubTotalAmount = 0;
foreach (var item in vm.Items)
{
item.Amount = item.UnitPrice * item.Quantity;
vm.SubTotalAmount += item.Amount.GetValueOrDefault();;
}
vm.Tax = vm.SubTotalAmount * 0.05m;
vm.TotalAmount = vm.SubTotalAmount * 1.05m;
return Ok(vm);
}
前端变更
...
<th>
<label asp-for="Items.FirstOrDefault().UnitPrice"></label>
</th>
...
<th>
<label asp-for="Items.FirstOrDefault().Amount"></label>
</th>
...
<p>
<label asp-for="SubTotalAmount"></label>
<label>@(Model?.SubTotalAmount)</label>
<input type="hidden"
readonly
asp-for="SubTotalAmount" />
</p>
<p>
<label asp-for="Tax"></label>
<label>@(Model?.Tax)</label>
<input type="hidden"
readonly
asp-for="Tax" />
</p>
<p>
<label asp-for="TotalAmount"></label>
<label>@(Model?.TotalAmount)</label>
<input type="hidden"
readonly
asp-for="TotalAmount" />
</p>
...
...
<td>
<input type="number"
name="Items[@(itemIndex)].UnitPrice"
step=1
min=0
onblur="Calculate()"
asp-for="UnitPrice" />
</td>
...
<td>
<label>@(Model?.Amount)</label>
<input type="hidden"
readonly
name="Items[@(itemIndex)].Amount"
asp-for="Amount" />
</td>
...
js 部份
// ...
window.CalculateUrl = '@Url.Action("Calculate")';
// ...
window.Calculate = function () {
fetch(CalculateUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'RequestVerificationToken': AntiForgeryToken,
},
body: $('form').serialize(),
})
.then(response => response.json())
.then(data => {
RenewAmounts(data);
})
}
window.RenewAmounts = function (viewModel) {
$('#Items > tr > td > input[name$="Amount"]').each( (index,dom) => {
const amount = viewModel?.Items[index]?.Amount;
$(dom)?.val(amount)
?.prev()?.text(amount);
});
$('#SubTotalAmount')?.val(viewModel?.SubTotalAmount)
?.prev()?.text(viewModel?.SubTotalAmount);
$('#Tax')?.val(viewModel?.Tax)
?.prev()?.text(viewModel?.Tax);
$('#TotalAmount')?.val(viewModel?.TotalAmount)
?.prev()?.text(viewModel?.TotalAmount);
}
// ...
画面如下:
目前页面上比较关键的实作如下:
之後等轻前端的部份介绍完毕後,再回头过来跟这个范例的语法进行比较 !
这篇先到这里,下一篇开始进入 轻前端 Vue 这个部份 !
堆叠(Stack)建立的方法 push: 新增元素 pop: 从顶端移除元素 peek: 查看顶端(...
Q: 效能跟效果之间怎麽取舍? A: 如果效果不复杂,用一些渲染成本比较高的写法也无妨 新属性搭配...
这篇会稍微从前几篇的内容抽离出来,因为中秋节连假家人来找,只能先做点简单的事情... Android...
AI system = Code (Algorithm/Model) + Data TL;DR 建...
废话不多说直接开始 我们点选菜单按钮会连结到这个表单 全域变数 string MyConnectio...