MVC控制器传递多个Model到视图,使用ViewData, ViewBag, 部分视图, TempData, ViewModel, Tuple
从控制器传递多个Model到视图,可以通过ViewData, ViewBag, PartialView, TempData, ViewModel,Tuple等,本篇逐一体验。本篇源码在github。
在视图页面,下拉框选择课程触发事件,分别显示老师课程表、学生上课表,如图:
相关的Model:
public class Course
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Teacher
{
public int Id { get; set; }
public string Name { get; set; }
public List<Course> Courses { get; set; }
}
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public List<Course> Courses { get; set; }
}
使用ViewData传递多个Model
□ HomeController
public ActionResult Index()
{
ViewData["Courses"] = _repository.GetCourses();
ViewData["Students"] = _repository.GetStudents();
ViewData["Teachers"] = _repository.GetTeachers();
return View();
}
□ Home/Index.cshtml
@using MvcApplication1.Models
@using System.Web.Helpers;
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>ViewDataDemo</title>
<script src="~/Scripts/jquery-1.8.2.js"></script>
<script type="text/javascript">
$(function () {
//隐藏
$('#students').hide();
$('#teachers').hide();
//点击课程下拉框
$('#sel').change(function() {
selectedCourseName = $('#sel').val().trim();
if (selectedCourseName == "--选择课程--") {
$('#students').hide();
$('#teachers').hide();
} else {
getTeacherTable();
getStudentTable();
$('#students').show();
$('#teachers').show();
}
});
});
var selectedCourseName;
//创建老师课程表
function getTeacherTable() {
$('#teachersTable').empty();
$('#teachersTable').append("<table id='tblTeachers'><tr><th>编号</th><th>姓名</th></tr></table>");
//把所有老师转换成json格式
var teachers = @Html.Raw(Json.Encode(ViewData["Teachers"]));
for (var i = 0; i < teachers.length; i++) {
var courses = teachers[i].Courses;
for (var j = 0; j < courses.length; j++) {
if (courses[j].Name == selectedCourseName) {
$('#tblTeachers').append("<tr><td>"+courses[i].Id+"</td><td>"+courses[i].Name+"</td></tr>");
}
}
}
}
//创建学生上课表
function getStudentTable() {
$('#studentsTable').empty();
$('#studentsTable').append("<table id='tblStudents'><tr><th>编号</th><th>姓名</th></tr></table>");
var students = @Html.Raw(Json.Encode(ViewData["Students"]));
for (var i = 0; i < students.length; i++) {
var courses = students[i].Courses;
for (var j = 0; j < courses.length; j++) {
if (courses[j].Name == selectedCourseName) {
$('#tblStudents').append("<tr><td>"+courses[j].Id+"</td><td>"+courses[j].Name+"</td></tr>");
}
}
}
}
</script>
</head>
<body>
<div>
<table>
<tr>
<td><h3>选择课程</h3></td>
<td>
<select id="sel">
<option>--选择课程--</option>
@foreach (var course in ViewData["Courses"] as List<Course>)
{
<option>@course.Name</option>
}
</select>
</td>
</tr>
</table>
</div>
<div id="teachers">
<h4>老师课程表</h4>
<div id="teachersTable"></div>
</div>
<div id="students">
<h4>学生上课表</h4>
<div id="studentsTable"></div>
</div>
</body>
</html>
@Html.Raw(Json.Encode(ViewData["Students"]))是把Model转换成json字符串,需要用到System.Web.Helpers,把此类库引用到项目,并且必须设置"复制到本地属性"为true,否则报错。
使用ViewBag传递多个Model
□ HomeController
public ActionResult ViewBagDemo()
{
ViewBag.Courses = _repository.GetCourses();
ViewBag.Students = _repository.GetStudents();
ViewBag.Teachers = _repository.GetTeachers();
return View();
}
□ Home/ViewBagDemo.cshtml
下拉框遍历课程改成:
@foreach (var course in ViewBag.Courses)
getTeacherTable()方法中改成:
var teachers = @Html.Raw(Json.Encode(ViewBag.Teachers));
getStudentTable()方法中改成:
var students = @Html.Raw(Json.Encode(ViewBag.Students));
使用部分视图传递多个Model
□ HomeController
public ActionResult PartialViewDemo()
{
List<Course> courses = _repository.GetCourses();
return View(courses);
}
public ActionResult StudentsToPVDemo(string courseName)
{
IEnumerable<Course> courses = _repository.GetCourses();
var selectedCourseId = (from c in courses
where c.Name == courseName
select c.Id).FirstOrDefault();
IEnumerable<Student> students = _repository.GetStudents();
var studentsInCourse = students.Where(s => s.Courses.Any(c => c.Id == selectedCourseId)).ToList();
return PartialView("StudentPV", studentsInCourse);
}
public ActionResult TeachersToPVDemo(string courseName)
{
IEnumerable<Course> courses = _repository.GetCourses();
var selectedCourseId = (from c in courses
where c.Name == courseName
select c.Id).FirstOrDefault();
IEnumerable<Teacher> teachers = _repository.GetTeachers();
var teachersForCourse = teachers.Where(t => t.Courses.Any(c => c.Id == selectedCourseId)).ToList();
return PartialView("TeacherPV", teachersForCourse);
}
□ Home/PartialViewDemo.cshmtl
@model IEnumerable<MvcApplication1.Models.Course>
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>PatialViewDemo</title>
<script src="~/Scripts/jquery-1.8.2.js"></script>
<script type="text/javascript">
$(function () {
//隐藏
$('#students').hide();
$('#teachers').hide();
//点击课程下拉框
$('#sel').change(function() {
selectedCourseName = $('#sel').val().trim();
if (selectedCourseName == "--选择课程--") {
$('#students').hide();
$('#teachers').hide();
} else {
getTeacherTable();
getStudentTable();
$('#students').show();
$('#teachers').show();
}
});
});
var selectedCourseName;
//创建老师课程表
function getTeacherTable() {
$.ajax({
url: "@Url.Action("TeachersToPVDemo","Home")",
type: 'Get',
data: { courseName: selectedCourseName },
success: function(data) {
$('#teachersTable').empty().append(data);
},
error: function() {
alert("sth wrong");
}
});
}
//创建学生上课表
function getStudentTable() {
$.ajax({
url: "@Url.Action("StudentsToPVDemo","Home")",
type: 'Get',
data: { courseName: selectedCourseName },
success: function (data) {
$('#studentsTable').empty().append(data);
},
error: function () {
alert("sth wrong");
}
});
}
</script>
</head>
<body>
<div>
<table>
<tr>
<td><h3>选择课程</h3></td>
<td>
<select id="sel">
<option>--选择课程--</option>
@foreach (var course in Model)
{
<option>@course.Name</option>
}
</select>
</td>
</tr>
</table>
</div>
<div id="teachers">
<h4>老师课程表</h4>
<div id="teachersTable"></div>
</div>
<div id="students">
<h4>学生上课表</h4>
<div id="studentsTable"></div>
</div>
</body>
</html>
□ TeacherPV.cshtml与StudentPV.cshtml
@model IEnumerable<MvcApplication1.Models.Teacher>
<table id="tblTeacherDetail">
<tr>
<th>编号</th>
<th>名称</th>
</tr>
@foreach (var item in Model)
{
<tr>
<td>@item.Id</td>
<td>@item.Name</td>
</tr>
}
</table>
使用TempData传递多个Model
□ HomeController
public ActionResult TempDataDemo()
{
//第一次从数据库读取数据放到TempData中,以后的请求从TempData中获取数据
TempData["Courses"] = _repository.GetCourses();
//让TempData保存数据,直到下一次请求
TempData.Keep("Courses");
return View();
}
public ActionResult TeachersTempData(string courseName)
{
var courses = TempData["Courses"] as IEnumerable<Course>;
//由于TempData["Courses"]还要被下一次请求,继续TempData保存数据
TempData.Keep("Courses");
var selectedCourseId = (from c in courses
where c.Name == courseName
select c.Id).FirstOrDefault();
IEnumerable<Teacher> teachers = _repository.GetTeachers();
var teachersForCourse = teachers.Where(t => t.Courses.Any(c => c.Id == selectedCourseId)).ToList();
return PartialView("TeacherPV", teachersForCourse);
}
public ActionResult StudentsTempData(string courseName)
{
var courses = TempData["Courses"] as IEnumerable<Course>;
//由于TempData["Courses"]还要被下一次请求,继续TempData保存数据
TempData.Keep("Courses");
var selectedCourseId = (from c in courses
where c.Name == courseName
select c.Id).FirstOrDefault();
IEnumerable<Student> students = _repository.GetStudents();
var studentsForCourse = students.Where(s => s.Courses.Any(c => c.Id == selectedCourseId)).ToList();
return PartialView("StudentPV", studentsForCourse);
}
□ Home/TempDataDemo.cshtml
下拉框遍历课程:
@foreach (var course in Model)
ajax请求老师课程表:
@Url.Action("TeachersTempData","Home")
ajax请求学生上课表:
@Url.Action("StudentsTempData","Home")
使用ViewModel传递多个Model
□ View Model
public class SchoolVm
{
public List<Course> Courses { get; set; }
public List<Student> Students { get; set; }
public List<Teacher> Teachers { get; set; }
}
□ HomeController
public ActionResult ViewModelDemoVM()
{
SchoolVm vm = new SchoolVm();
vm.Courses = _repository.GetCourses();
vm.Teachers = _repository.GetTeachers();
vm.Students = _repository.GetStudents();
return View(vm);
}
□ Home/ViewModelDemoVM.cshtml
@model MvcApplication1.Models.SchoolVm
下拉框遍历课程:
@foreach (var course in Model.Courses)
ajax请求老师课程表和学生上课表:
@Html.Raw(Json.Encode(Model.Teachers))
@Html.Raw(Json.Encode(Model.Students))
使用Tuple传递多个Model
□ HomeController
public ActionResult TupleDemo()
{
var allModels = new Tuple<List<Course>, List<Teacher>, List<Student>>(_repository.GetCourses(),
_repository.GetTeachers(), _repository.GetStudents()) {};
return View(allModels);
}
□ Home/TupleDemo.cshtml
@model Tuple <List <MvcApplication1.Models.Course>, List <MvcApplication1.Models.Teacher>, List <MvcApplication1.Models.Student>>
下拉框遍历课程:
@foreach (var course in Model.Item1)
ajax请求老师课程表和学生上课表:
@Html.Raw(Json.Encode(Model.Item2))
@Html.Raw(Json.Encode(Model.Item3))
参考资料:
※ Using Multiple Models in a View in ASP.NET MVC 4 / MVC 5