[英]Asp Net Core. Multiple partial views in one page. Passing Models and Calling Actions
我是一名學生,剛開始使用 MVC Asp.net。
我正在嘗試創建一個預訂系統,並希望通過使用各種手風琴將所有步驟都放在一頁上。
我試圖了解我是否能夠通過使用幾種不同的模型並從不同的局部視圖調用 asp-actions 來實現它。
目前,如果我在 SittingTimes 的局部視圖上設置 model 屬性,它會顯示為 null 參考,因為必須在執行 Sitting 操作后設置 SittingTimeVM。但如果我不設置它,它只會返回一個完全獨立的局部視圖頁。
我該怎么辦? 還是我應該研究創建 One Page 系統的不同選項?
Controller:
public async Task<IActionResult> Restaurants()
{
var company = await _context.Companies.Include(c => c.Restaurants).FirstAsync(c => c.Id == 1);
return View(company);
}
public async Task<IActionResult> SittingOne(int restaurantId)
{
var restaurant = await _context.Restaurants.FirstOrDefaultAsync(s => s.Id == restaurantId);
var parent = new Models.ParentModel
{
sittingVM = CreateNewSittingVM(restaurantId)
};
return View(parent);
}
public Models.Sittings.SittingVM CreateNewSittingVM(int restaurantId) => new
Models.Sittings.SittingVM
{
RestaurantId = restaurantId,
SittingType = new SelectList(_context.SittingTypes, "Id", "Description")
};
[HttpPost]
public async Task<IActionResult> SittingTimes(Models.Sittings.SittingVM s)
{
var allSittings = await _context.Sitings.Where(st => st.StartTime.Day ==
s.Date.Day && st.SittingTypeId == s.SittingTypeId).FirstOrDefaultAsync();
if (allSittings == null)
{
s.ErrorNumber = 1;
return RedirectToAction("ErrorNoSitting", s);
}
if (allSittings.isClosed == true)
{
s.ErrorNumber = 2;
return RedirectToAction("ErrorNoSitting", s);
}
var sittimes = new SittingTimesVM
{
SittingId = allSittings.Id,
NumberOfGuests = s.NumberOfGuests,
Date = s.Date,
RestaurantId = s.RestaurantId,
SittingsStart = allSittings.StartTime,
SittingsEnd = allSittings.EndTime,
CutOffTime = allSittings.CutOff,
};
var sitting = await _context.Sitings.FirstOrDefaultAsync(r => r.Id == sittimes.SittingId);
if (sitting.Capacity < sittimes.NumberOfGuests)
{
s.ErrorNumber = 3;
return RedirectToAction("ErrorNoSitting", s);
}
return PartialView("SittingTimes",sittimes);
}
包含部分視圖的主視圖:
@model ReservationSystemTeamD.Models.ParentModel;
<div class="accordion">
<div class="accordion-item">
<h2 class="accordion-header" id="headingOne">
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseOne" aria-expanded="false" aria-controls="collapseOne">
Choose Date
</button>
</h2>
<div id="collapseOne" class="accordion-collapse collapse show" aria-labelledby="headingOne" data-bs-parent="#accordionExample">
<div class="accordion-body">
<partial name="Sittings" model="Model.sittingVM" />
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header" id="headingTwo">
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
Choose Time
</button>
</h2>
<div id="collapseTwo" class="accordion-collapse collapse show" aria-labelledby="headingTwo" data-bs-parent="#accordionExample">
<div class="accordion-body" id="div2">
<partial name="SittingTimes"/>
</div>
</div>
</div>
</div>
家長 Model:
using ReservationSystemTeamD.Models.Sittings;
namespace ReservationSystemTeamD.Models
{
public class ParentModel
{
public SittingVM sittingVM { get; set; }
public SittingTimesVM sittingTimesVM { get; set; }
}
}
部分坐姿:
@model ReservationSystemTeamD.Models.Sittings.SittingVM
<form asp-action="SittingTimes" method="post">
<div class="form-group row bg-info bg-gradient p-3">
<div class="col-md-4">
<label asp-for="Date" class="control-label">Choose the Date</label>
<input class="form-control" id="datefield" type="date" min="" value="" asp-for="Date" />
<span asp-validation-for="Date" style="color: red;"></span>
</div>
<div class="col-md-3">
<label asp-for="NumberOfGuests" class="control-aslabel">Number of Guests</label>
<input type="number" asp-for="NumberOfGuests" id="NumberofGuest" class="form-control" min=1 max=10 />
<span asp-validation-for="NumberOfGuests" style="color: red;"></span>
</div>
<div class="col-md-3">
<label asp-for=SittingTypeId class="control-label">Sitting Type</label>
<select asp-for=SittingTypeId asp-items=Model.SittingType type="text" class="form-select">
<option value="" data-val="true">Please Select</option>
</select>
<span asp-validation-for="SittingTypeId" style="color: red;"></span>
</div>
<div class="col-md-2 mt-4">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</div>
<input type="hidden" asp-for=RestaurantName />
<input type="hidden" asp-for=RestaurantId />
<input type="hidden" asp-for=SittingType />
<input type="hidden" asp-for=SittingTypeId />
</form>
<script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
<script>
var today = new Date();
var dd = today.getDate();
var mm = today.getMonth() + 1;
var yyyy = today.getFullYear();
if (dd < 10) {
dd = '0' + dd;
}
if (mm < 10) {
mm = '0' + mm;
}
today = yyyy + '-' + mm + '-' + dd;
document.getElementById("datefield").setAttribute("min", today).setAttribute("value", today);
</script>
@section Scripts {
<partial name="_ValidationScriptsPartial" />
}
坐VM:
using Microsoft.AspNetCore.Mvc.Rendering;
using System.ComponentModel.DataAnnotations;
namespace ReservationSystemTeamD.Models.Sittings
{
public class SittingVM
{
[Required(ErrorMessage = "Please enter a date")]
[DataType(DataType.Date)]
public DateTime Date { get; set; }
public int RestaurantId { get; set; }
public string RestaurantName { get; set; }
public int NumberOfGuests { get; set; }
public int? SittingTypeId { get; set; }
public SelectList SittingType { get; set; }
public List<SittingTimesVM>? SittingTimes { get; set; }
public int ErrorNumber { get; set; }
}
}
SittingTimesVM:
using System.ComponentModel.DataAnnotations;
namespace ReservationSystemTeamD.Models.Sittings
{
public class SittingTimesVM
{
public int SittingId { get; set; }
public int SittingTypeId { get; set; }
public DateTime Date { get; set; }
public int RestaurantId { get; set; }
public int NumberOfGuests { get; set; }
[DataType(DataType.Time)]
[DisplayFormat(DataFormatString = "{0:HH:mm tt}")]
public DateTime ChosenTime { get; set; }
public DateTime SittingsStart { get; set; }
public DateTime SittingsEnd { get; set; }
public int CutOffTime { get; set; }
public string Email { get; set; }
}
}
局部視圖——顧名思義——只是另一個視圖的一部分。
在 MVC 中,您創建一個 Model,一個帶有操作的 Controller 和一個通過該操作提供服務的視圖。 視圖現在已完全構建,它的視圖 model 已創建,所有內容都將提供給請求者。
在你的情況下你剛剛寫了
<partial name="SittingTimes"/>
這表明“在當前主視圖中呈現此部分,然后將其提供給請求方”。 一切都在一個 controller 動作中完成。
如果你想在你的部分中使用數據,你將不得不使用這樣的東西:
@await Html.PartialAsync("_PartialName", model)
其中 model 持有 object。
如果您想在一個頁面中使用不同的 controller 操作,您將不得不使用一些 AJAX看這里。
您走在分離關注點的正確道路上,但只是對 MVC 有誤解。 繼續學習;)
您可以嘗試在SittingOne(int restaurantId)
中創建 settingTimesVM,並將ParentModel.sittingTimesVM
傳遞給部分視圖,如下所示:
public async Task<IActionResult> SittingOne(int restaurantId)
{
var restaurant = await _context.Restaurants.FirstOrDefaultAsync(s => s.Id == restaurantId);
var parent = new Models.ParentModel
{
sittingVM = CreateNewSittingVM(restaurantId)
};
parent.SittingTimesVM = CreateNewSittingTimesVM(parent.SittingVM);
return View(parent);
}
public Models.Sittings.SittingVM CreateNewSittingVM(int restaurantId) => new
Models.Sittings.SittingVM
{
RestaurantId = restaurantId,
SittingType = new SelectList(_context.SittingTypes, "Id", "Description")
};
public async Models.Sittings.SittingTimesVM CreateNewSittingTimesVM(Models.Sittings.SittingVM s)
{
var allSittings = await _context.Sitings.Where(st => st.StartTime.Day ==
s.Date.Day && st.SittingTypeId == s.SittingTypeId).FirstOrDefaultAsync();
if (allSittings == null)
{
s.ErrorNumber = 1;
return RedirectToAction("ErrorNoSitting", s);
}
if (allSittings.isClosed == true)
{
s.ErrorNumber = 2;
return RedirectToAction("ErrorNoSitting", s);
}
var sittimes = new SittingTimesVM
{
SittingId = allSittings.Id,
NumberOfGuests = s.NumberOfGuests,
Date = s.Date,
RestaurantId = s.RestaurantId,
SittingsStart = allSittings.StartTime,
SittingsEnd = allSittings.EndTime,
CutOffTime = allSittings.CutOff,
};
return sittimes;
}
看法:
@await Html.PartialAsync("SittingTimes", Model.sittingTimesVM)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.