뷰에서 여러 모델
한 번에 두 가지 모델을 원합니다. 페이지가 모두 포함 LoginViewModel
하고 RegisterViewModel
.
예 :
public class LoginViewModel
{
public string Email { get; set; }
public string Password { get; set; }
}
public class RegisterViewModel
{
public string Name { get; set; }
public string Email { get; set; }
public string Password { get; set; }
}
이 2 개의 ViewModel을 보유하는 다른 ViewModel을 만들어야합니까?
public BigViewModel
{
public LoginViewModel LoginViewModel{get; set;}
public RegisterViewModel RegisterViewModel {get; set;}
}
뷰로 가져 오기 위해 유효성 검사 속성이 필요합니다. 이것이 ViewModels가 필요한 이유입니다.
(없이 BigViewModel
) 와 같은 다른 방법이 없습니까?
@model ViewModel.RegisterViewModel
@using (Html.BeginForm("Login", "Auth", FormMethod.Post))
{
@Html.TextBoxFor(model => model.Name)
@Html.TextBoxFor(model => model.Email)
@Html.PasswordFor(model => model.Password)
}
@model ViewModel.LoginViewModel
@using (Html.BeginForm("Login", "Auth", FormMethod.Post))
{
@Html.TextBoxFor(model => model.Email)
@Html.PasswordFor(model => model.Password)
}
많은 방법이 있습니다 ...
BigViewModel을 사용하여 다음을 수행하십시오.
@model BigViewModel @using(Html.BeginForm()) { @Html.EditorFor(o => o.LoginViewModel.Email) ... }
2 개의 추가보기를 만들 수 있습니다
Login.cshtml
@model ViewModel.LoginViewModel @using (Html.BeginForm("Login", "Auth", FormMethod.Post)) { @Html.TextBoxFor(model => model.Email) @Html.PasswordFor(model => model.Password) }
register.cshtml 같은 것
생성 후 메인 뷰에서 렌더링하고 뷰 모델 / 뷰 데이터를 전달해야합니다.
따라서 다음과 같이 될 수 있습니다.
@{Html.RenderPartial("login", ViewBag.Login);} @{Html.RenderPartial("register", ViewBag.Register);}
또는
@{Html.RenderPartial("login", Model.LoginViewModel)} @{Html.RenderPartial("register", Model.RegisterViewModel)}
웹 사이트의 아약스 부분을 사용하면 더 독립적이됩니다.
iframes
하지만 아마도 그렇지 않습니다.
Html.RenderAction
이를 위해 PartialViewResults를 사용하는 것이 좋습니다 . 동일한 데이터를 표시 할 수 있지만 각 부분 뷰에는 여전히 단일 뷰 모델이 있으며BigViewModel
따라서 뷰에는 다음과 같은 내용이 포함됩니다.
@Html.RenderAction("Login")
@Html.RenderAction("Register")
어디 Login
&은 Register
다음과 같이 정의 컨트롤러에서 모두 작업입니다 :
public PartialViewResult Login( )
{
return PartialView( "Login", new LoginViewModel() );
}
public PartialViewResult Register( )
{
return PartialView( "Register", new RegisterViewModel() );
}
Login
&는 Register
다음, 또는 공유 폴더에 하나 현재보기 폴더에 존재하는 사용자 컨트롤 것과 같은 것을 좋아하는 것 :
/Views/Shared/Login.cshtml : (또는 /Views/MyView/Login.cshtml)
@model LoginViewModel
@using (Html.BeginForm("Login", "Auth", FormMethod.Post))
{
@Html.TextBoxFor(model => model.Email)
@Html.PasswordFor(model => model.Password)
}
/Views/Shared/Register.cshtml : (또는 /Views/MyView/Register.cshtml)
@model ViewModel.RegisterViewModel
@using (Html.BeginForm("Login", "Auth", FormMethod.Post))
{
@Html.TextBoxFor(model => model.Name)
@Html.TextBoxFor(model => model.Email)
@Html.PasswordFor(model => model.Password)
}
거기에는 각각의 작업마다 하나의 컨트롤러 작업,보기 및보기 파일이 있으며 완전히 다른 것으로 서로에 의존하지 않습니다.
다른 방법은 다음을 사용하는 것입니다.
@model Tuple<LoginViewModel,RegisterViewModel>
다른 예제를 위해 뷰와 컨트롤러에서이 방법을 사용하는 방법을 설명 했습니다. ASP MVC 3에서 한 뷰에 두 개의 모델
귀하의 경우 다음 코드를 사용하여 구현할 수 있습니다.
보기에서 :
@using YourProjectNamespace.Models;
@model Tuple<LoginViewModel,RegisterViewModel>
@using (Html.BeginForm("Login1", "Auth", FormMethod.Post))
{
@Html.TextBoxFor(tuple => tuple.Item2.Name, new {@Name="Name"})
@Html.TextBoxFor(tuple => tuple.Item2.Email, new {@Name="Email"})
@Html.PasswordFor(tuple => tuple.Item2.Password, new {@Name="Password"})
}
@using (Html.BeginForm("Login2", "Auth", FormMethod.Post))
{
@Html.TextBoxFor(tuple => tuple.Item1.Email, new {@Name="Email"})
@Html.PasswordFor(tuple => tuple.Item1.Password, new {@Name="Password"})
}
참고 양식을 구축 할 때 내가 수동으로 이름 변경 즉, 각 속성에 대한 속성. 이 작업을 수행해야합니다. 그렇지 않으면 값이 처리를 위해 관련 메서드로 전송 될 때 모델 형식의 메서드 매개 변수에 제대로 매핑되지 않습니다. 별도의 메소드를 사용하여 이러한 양식을 개별적으로 처리하는 것이 좋습니다.이 예에서는 Login1 및 Login2 메소드를 사용했습니다. Login1 메소드에는 RegisterViewModel 유형의 매개 변수가 필요하고 Login2에는 LoginViewModel 유형의 매개 변수가 필요합니다.
액션 링크가 필요한 경우 다음을 사용할 수 있습니다.
@Html.ActionLink("Edit", "Edit", new { id=Model.Item1.Id })
보기에 대한 컨트롤러의 메소드에서 Tuple 유형의 변수를 작성한 후보기로 전달해야합니다.
예:
public ActionResult Details()
{
var tuple = new Tuple<LoginViewModel, RegisterViewModel>(new LoginViewModel(),new RegisterViewModel());
return View(tuple);
}
또는 LoginViewModel 및 RegisterViewModel의 두 인스턴스를 값으로 채운 후보기로 전달할 수 있습니다.
여러 뷰 모델이 포함 된 뷰 모델을 사용하십시오.
namespace MyProject.Web.ViewModels
{
public class UserViewModel
{
public UserDto User { get; set; }
public ProductDto Product { get; set; }
public AddressDto Address { get; set; }
}
}
당신의 관점에서 :
@model MyProject.Web.ViewModels.UserViewModel
@Html.LabelFor(model => model.User.UserName)
@Html.LabelFor(model => model.Product.ProductName)
@Html.LabelFor(model => model.Address.StreetName)
이 두 가지 견해를 보유하는 다른 견해를 만들어야합니까?
답변 : 아니요
(BigViewModel없이) 다른 방법이 없습니까?
예 , Tuple을 사용할 수 있습니다 (여러 모델의 관점에서 마술을 가져옵니다).
암호:
@model Tuple<LoginViewModel, RegisterViewModel>
@using (Html.BeginForm("Login", "Auth", FormMethod.Post))
{
@Html.TextBoxFor(tuple=> tuple.Item.Name)
@Html.TextBoxFor(tuple=> tuple.Item.Email)
@Html.PasswordFor(tuple=> tuple.Item.Password)
}
@using (Html.BeginForm("Login", "Auth", FormMethod.Post))
{
@Html.TextBoxFor(tuple=> tuple.Item1.Email)
@Html.PasswordFor(tuple=> tuple.Item1.Password)
}
이 ModelCollection.cs를 모델에 추가
using System;
using System.Collections.Generic;
namespace ModelContainer
{
public class ModelCollection
{
private Dictionary<Type, object> models = new Dictionary<Type, object>();
public void AddModel<T>(T t)
{
models.Add(t.GetType(), t);
}
public T GetModel<T>()
{
return (T)models[typeof(T)];
}
}
}
제어 장치:
public class SampleController : Controller
{
public ActionResult Index()
{
var model1 = new Model1();
var model2 = new Model2();
var model3 = new Model3();
// Do something
var modelCollection = new ModelCollection();
modelCollection.AddModel(model1);
modelCollection.AddModel(model2);
modelCollection.AddModel(model3);
return View(modelCollection);
}
}
보기:
enter code here
@using Models
@model ModelCollection
@{
ViewBag.Title = "Model1: " + ((Model.GetModel<Model1>()).Name);
}
<h2>Model2: @((Model.GetModel<Model2>()).Number</h2>
@((Model.GetModel<Model3>()).SomeProperty
그렇게하는 간단한 방법
우리는 먼저 모든 모델을 호출 할 수 있습니다
@using project.Models
그런 다음 뷰백으로 모델을 보내십시오.
// for list
ViewBag.Name = db.YourModel.ToList();
// for one
ViewBag.Name = db.YourModel.Find(id);
그리고보기
// for list
List<YourModel> Name = (List<YourModel>)ViewBag.Name ;
//for one
YourModel Name = (YourModel)ViewBag.Name ;
그런 다음 모델처럼 쉽게 사용하십시오.
내 솔루션 이이 스택 오버 플로우 페이지에 제공된 답변과 같다고 말하고 싶습니다 : ASP.NET MVC 4, 하나의보기에서 여러 모델?
그러나 제 경우에는 컨트롤러에서 사용한 linq 쿼리가 작동하지 않았습니다.
이것은 쿼리라고합니다 :
var viewModels =
(from e in db.Engineers
select new MyViewModel
{
Engineer = e,
Elements = e.Elements,
})
.ToList();
결과적으로, "보기에서 당신이보기 모델 모음을 사용하고 있음을 지정하십시오"는 나에게도 효과가 없었습니다.
그러나 그 솔루션의 약간의 변형이 저에게 효과적이었습니다. 이것이 누군가를 도울 수있는 경우 내 해결책입니다.
여기에 하나의 팀이 있지만 해당 팀에 여러 보드가있을 수 있음을 알 수있는 뷰 모델이 있습니다 (그리고 내 네임 폴더 btw에 ViewModels 폴더가 있으므로 네임 스페이스가 있습니다).
namespace TaskBoard.Models.ViewModels
{
public class TeamBoards
{
public Team Team { get; set; }
public List<Board> Boards { get; set; }
}
}
이제 이것은 내 컨트롤러입니다. 이것은 위에서 언급 한 링크의 솔루션과 가장 큰 차이점입니다. 뷰에 다르게 보내기 위해 ViewModel을 빌드합니다.
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
TeamBoards teamBoards = new TeamBoards();
teamBoards.Boards = (from b in db.Boards
where b.TeamId == id
select b).ToList();
teamBoards.Team = (from t in db.Teams
where t.TeamId == id
select t).FirstOrDefault();
if (teamBoards == null)
{
return HttpNotFound();
}
return View(teamBoards);
}
그런 다음 내 견해로는 목록으로 지정하지 않습니다. 나는 단지 "@model TaskBoard.Models.ViewModels.TeamBoards"를하고 팀 보드를 반복 할 때 각각에 대해서만 필요합니다. 여기 내 견해가 있습니다 :
@model TaskBoard.Models.ViewModels.TeamBoards
@{
ViewBag.Title = "Details";
}
<h2>Details</h2>
<div>
<h4>Team</h4>
<hr />
@Html.ActionLink("Create New Board", "Create", "Board", new { TeamId = @Model.Team.TeamId}, null)
<dl class="dl-horizontal">
<dt>
@Html.DisplayNameFor(model => Model.Team.Name)
</dt>
<dd>
@Html.DisplayFor(model => Model.Team.Name)
<ul>
@foreach(var board in Model.Boards)
{
<li>@Html.DisplayFor(model => board.BoardName)</li>
}
</ul>
</dd>
</dl>
</div>
<p>
@Html.ActionLink("Edit", "Edit", new { id = Model.Team.TeamId }) |
@Html.ActionLink("Back to List", "Index")
</p>
ASP.NET MVC를 처음 접했기 때문에 이것을 알아내는 데 약간의 시간이 걸렸습니다. 따라서이 게시물이 누군가가 더 짧은 기간 내에 프로젝트를 위해 그것을 파악하는 데 도움이되기를 바랍니다. :-)
내 조언은 큰보기 모델을 만드는 것입니다.
public BigViewModel
{
public LoginViewModel LoginViewModel{get; set;}
public RegisterViewModel RegisterViewModel {get; set;}
}
예를 들어 Index.cshtml에서 부분이 2 개인 경우 :
@addTagHelper *,Microsoft.AspNetCore.Mvc.TagHelpers
@model .BigViewModel
@await Html.PartialAsync("_LoginViewPartial", Model.LoginViewModel)
@await Html.PartialAsync("_RegisterViewPartial ", Model.RegisterViewModel )
컨트롤러에서 :
model=new BigViewModel();
model.LoginViewModel=new LoginViewModel();
model.RegisterViewModel=new RegisterViewModel();
하나 개의 새로운 모델의 클래스와 속성 생성
LoginViewModel
및RegisterViewModel
:public class UserDefinedModel() { property a1 as LoginViewModel property a2 as RegisterViewModel }
그런 다음
UserDefinedModel
귀하의 관점에서 사용 하십시오.
ViewBag 또는 View Data에서 항상 두 번째 객체를 전달할 수 있습니다.
IEnumerable을 사용한 간단한 예입니다.
검색 기준 (SearchParams 모델)이있는 양식과 결과에 대한 그리드라는 두 가지 모델을 뷰에서 사용하고 있었고 IEnumerable 모델과 다른 모델을 동일한 뷰에 추가하는 방법에 어려움을 겪었습니다. 여기에 내가 생각해 낸 것이 누군가에게 도움이되기를 바랍니다.
@using DelegatePortal.ViewModels;
@model SearchViewModel
@using (Html.BeginForm("Search", "Delegate", FormMethod.Post))
{
Employee First Name
@Html.EditorFor(model => model.SearchParams.FirstName,
new { htmlAttributes = new { @class = "form-control form-control-sm " } })
<input type="submit" id="getResults" value="SEARCH" class="btn btn-primary btn-lg btn-block" />
}
<br />
@(Html
.Grid(Model.Delegates)
.Build(columns =>
{
columns.Add(model => model.Id).Titled("Id").Css("collapse");
columns.Add(model => model.LastName).Titled("Last Name");
columns.Add(model => model.FirstName).Titled("First Name");
})
...)
SearchViewModel.cs :
namespace DelegatePortal.ViewModels
{
public class SearchViewModel
{
public IEnumerable<DelegatePortal.Models.DelegateView> Delegates { get; set; }
public SearchParamsViewModel SearchParams { get; set; }
....
DelegateController.cs :
// GET: /Delegate/Search
public ActionResult Search(String firstName)
{
SearchViewModel model = new SearchViewModel();
model.Delegates = db.Set<DelegateView>();
return View(model);
}
// POST: /Delegate/Search
[HttpPost]
public ActionResult Search(SearchParamsViewModel searchParams)
{
String firstName = searchParams.FirstName;
SearchViewModel model = new SearchViewModel();
if (firstName != null)
model.Delegates = db.Set<DelegateView>().Where(x => x.FirstName == firstName);
return View(model);
}
SearchParamsViewModel.cs :
namespace DelegatePortal.ViewModels
{
public class SearchParamsViewModel
{
public string FirstName { get; set; }
}
}
참고 URL : https://stackoverflow.com/questions/4764011/multiple-models-in-a-view
'Programing' 카테고리의 다른 글
Visual Studio에서 Rebuild와 Clean + Build의 차이점 (0) | 2020.03.19 |
---|---|
세트에서 요소 얻기 (0) | 2020.03.19 |
결과가 비어있을 때 LINQ는 무엇을 반환합니까? (0) | 2020.03.19 |
Javascript를 사용하여 CSS 파일을로드하는 방법은 무엇입니까? (0) | 2020.03.19 |
사전에 사전을 추가 하시겠습니까? (0) | 2020.03.19 |