Closed. This question needs to be more focused。它当前不接受答案。
想改善这个问题吗?更新问题,使其仅通过editing this post专注于一个问题。
3年前关闭。
这是学习ASP.NET MVC 5的人的一个新手问题。我想创建一个Web应用程序屏幕,用户可以在其中编辑树状数据结构。我不确定如何遵循最佳做法。
为了简单起见,我们假设它是一个两级数据结构,每个驾驶员可以驾驶多辆汽车的驾驶员列表:
我需要能够在同一屏幕上添加/删除/编辑驾驶员(及其汽车)。这是否意味着用户进行的每项更改(例如,添加一辆新车,然后更改其
如果是这样,如果我想在客户端上允许对多个模型进行更改,然后再将所有更新提交回我的控制器,是否需要使用MVVM框架(例如Angular或Knockout)?还是可以使用裸ASP.NET MVC来完成某些工作?
请注意,我不需要单页Web应用程序,我只想在执行HTTP发布操作之前在客户端缓存用户更新。
UPDATE,因此该Web应用程序当前可以经典的MVC方式工作:首先是具有驾驶员列表的视图,然后是具有汽车列表的视图,然后是一辆汽车。有一个单独的HTTP请求来呈现每个视图。
我想要的是让用户在同一视图内编辑整个结构,然后单击“更新”按钮。那时,我希望整个数据结构的更新的POCO模型可以提交并在MVC控制器中使用。我想要一个客户端JavaScript框架(Knockout,Angular,Aurelia等)来为我处理生成和更新
赏金将奖励给您一个答案,并给出相关示例代码,说明如何做到这一点。
如您所见,该控制器是一个非常准系统,它们中最大的方法是GetDriversModel(),该方法优先处理带有示例数据的页面。
在这里,您可能会执行类似查询长期存储中要在客户端渲染的树的操作。很可能会用某种形式的ID进行标记,但是由于这些细节不在您的问题中,因此我将其省略。您可以通过此示例轻松地弄清楚。
最有趣的部分实际上是在页面上,我使用敲除为DriversModel数据结构构建了一个渲染器。首先,让我们检查一下JavaScript:
KO视图的核心是ViewModel:
在其中,我们定义了两种从树中添加/删除驱动程序的方法,以及将内容发布回服务器的方法。 ViewModel非常简单(本示例中几乎所有内容)。请注意,在JS完成查询服务器数据之后,我已经在列表中添加了另一个随机驱动程序。这样做只是为了好玩(我也在做实验)。
以下是其余实体的ViewModel:
如您所见,所有这些对象内部都有一些初始化逻辑,在这些逻辑中,我们将从服务器获取的JSON对象映射到客户端抽象。您还可以注意到,它们不遵循JavaScript对象的命名约定。我故意这样做,以便在客户端上完成与MVC的映射时,MVC在将它们映射到C#对象时不会出现问题。
从长远来看,这可能不是一件好事,但是为了简单起见,它会做到。
因此,基本上发生的是,当我们的DriversViewModel从服务器请求项目时,它将所有数据映射到Knockout友好的抽象中,随着Knockout的更改而对其进行跟踪。剩下的就是实际上告诉Knockout使用此ViewModel:
现在敲除已准备就绪,可以使用这些对象了,现在是时候构建UI部件了。
使用这些KO绑定的页面如下所示:
如您所见,没有什么棘手的问题。关于这一切的最棘手的部分是知道要使用哪个数据绑定指令,并跟踪在哪个上下文中实际使用哪个ViewModel。 (当您使用在不同ViewModel上定义的不同添加/删除功能时,这一点很重要。)
就是这样。这是一个很好的解决方案屏幕截图:
![c# - 使用ASP.MVC编辑树状结构-LMLPHP c# - 使用ASP.MVC编辑树状结构-LMLPHP]()
虽然看起来很凌乱,但可以完成工作。
单击相应的“添加”按钮时,会添加汽车或驾驶员。
单击“更新”按钮将组装整个树并将其重新发布到服务器,在此通过ASP.NET MVC magic的功能将其转换为POCO。
这是代码的binsbin,因此您可以复制粘贴并自己查看。您将不得不花一些时间在MVC项目上,但是我相信您可以解决这个问题。
页:
http://pastebin.com/2aGkEHEN
控制器:
http://pastebin.com/nZaufcpw
重要说明:
如果您确实想执行类似的操作,则可能需要跟踪用户如何更改数据,而不是仅获取整个更改后的结构并覆盖旧数据。
而不是在示例中向您展示的简单方法,我将尝试跟踪用户对树所做的更改,然后将某种更改集(而不是整个结构)发送到服务器。这样,您可以在事务中应用变更集并获得相同的结果,但带宽更少,一致性更高。
想改善这个问题吗?更新问题,使其仅通过editing this post专注于一个问题。
3年前关闭。
这是学习ASP.NET MVC 5的人的一个新手问题。我想创建一个Web应用程序屏幕,用户可以在其中编辑树状数据结构。我不确定如何遵循最佳做法。
为了简单起见,我们假设它是一个两级数据结构,每个驾驶员可以驾驶多辆汽车的驾驶员列表:
public class Car
{
public string Name; { get; set; }
public string Code; { get; set; }
}
public class Driver
{
public string FullName { get; set; }
public List<Cars> { get; set; }
}
public class Model
{
public List<Driver> Drivers { get; set; }
}
我需要能够在同一屏幕上添加/删除/编辑驾驶员(及其汽车)。这是否意味着用户进行的每项更改(例如,添加一辆新车,然后更改其
Code
)都需要提交表单(即,对我的控制器进行点击)并将新视图发送回客户端?如果是这样,如果我想在客户端上允许对多个模型进行更改,然后再将所有更新提交回我的控制器,是否需要使用MVVM框架(例如Angular或Knockout)?还是可以使用裸ASP.NET MVC来完成某些工作?
请注意,我不需要单页Web应用程序,我只想在执行HTTP发布操作之前在客户端缓存用户更新。
UPDATE,因此该Web应用程序当前可以经典的MVC方式工作:首先是具有驾驶员列表的视图,然后是具有汽车列表的视图,然后是一辆汽车。有一个单独的HTTP请求来呈现每个视图。
我想要的是让用户在同一视图内编辑整个结构,然后单击“更新”按钮。那时,我希望整个数据结构的更新的POCO模型可以提交并在MVC控制器中使用。我想要一个客户端JavaScript框架(Knockout,Angular,Aurelia等)来为我处理生成和更新
DefaultModelBinder
索引器,因此我不必手动管理索引器(即<input name="Drivers[2].Cars[1].Name" ... />
等) ,有关更多详细信息,请参见this q/a)。赏金将奖励给您一个答案,并给出相关示例代码,说明如何做到这一点。
最佳答案
因此,您想要我们帮助您的事情需要花费很多时间来构建,但实际上却非常简单(为公平起见,大多数基本的KO教程中都有足够的信息来完成所有这些工作。)
因此,我用3种方法构建了一个页面和一个MVC控制器:一个用于页面本身,另外两个用于GETTING或POSTING数据。
这是控制器的代码:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpPost]
public JsonResult PostDriversModel(DriversModel model)
{
return Json(new { Success = true }, JsonRequestBehavior.AllowGet);
}
[HttpGet]
public JsonResult GetDriversModel()
{
var model = new DriversModel
{
Drivers = new List<Driver>
{
new Driver
{
FullName = "John Doe",
Cars = new List<Car>
{
new Car {Code = "car0", Name = "Amazing car"},
new Car {Code = "car1", Name = "Cool car"}
},
},
new Driver
{
FullName = "Johnny Dough",
Cars = new List<Car>
{
new Car {Code = "car2", Name = "Another Amazing car"}, new Car {Code = "car3", Name = "Another Cool car"}
}
},
}
};
return Json(model, JsonRequestBehavior.AllowGet);
}
}
如您所见,该控制器是一个非常准系统,它们中最大的方法是GetDriversModel(),该方法优先处理带有示例数据的页面。
在这里,您可能会执行类似查询长期存储中要在客户端渲染的树的操作。很可能会用某种形式的ID进行标记,但是由于这些细节不在您的问题中,因此我将其省略。您可以通过此示例轻松地弄清楚。
最有趣的部分实际上是在页面上,我使用敲除为DriversModel数据结构构建了一个渲染器。首先,让我们检查一下JavaScript:
KO视图的核心是ViewModel:
function DriversViewModel() {
var self = this;
self.Drivers = ko.observableArray([]);
self.addDriver = function() {
self.Drivers.push(new DriverModel({ FullName: 'Mr. Noname', Cars: [] }));
};
self.removeDriver = function(driver) {
self.Drivers.remove(driver);
};
self.update = function() {
$.ajax("/Home/PostDriversModel", {
data: ko.toJSON({ Drivers: self.Drivers }),
type: "post", contentType: "application/json",
success: function () { alert('Success!'); }
});
}
$.getJSON('/Home/GetDriversModel', function (data) {
var drivers = data.Drivers.map(function (driver) { return new DriverModel(driver); });
drivers.push(new DriverModel({ Cars: [], FullName: 'Mr Nocars' }));
self.Drivers(drivers);
});
}
在其中,我们定义了两种从树中添加/删除驱动程序的方法,以及将内容发布回服务器的方法。 ViewModel非常简单(本示例中几乎所有内容)。请注意,在JS完成查询服务器数据之后,我已经在列表中添加了另一个随机驱动程序。这样做只是为了好玩(我也在做实验)。
以下是其余实体的ViewModel:
function CarModel(data) {
var self = this;
self.Code = ko.observable(data.Code);
self.Name = ko.observable(data.Name);
}
function DriverModel(data) {
var self = this;
self.addCar = function () {
self.Cars.push(new CarModel({ Name: 'Tank', Code: '__' }));
};
self.removeCar = function (car) {
self.Cars.remove(car);
};
self.Cars = ko.observableArray(data.Cars.map(function(car) { return new CarModel(car); }));
self.FullName = ko.observable(data.FullName);
}
如您所见,所有这些对象内部都有一些初始化逻辑,在这些逻辑中,我们将从服务器获取的JSON对象映射到客户端抽象。您还可以注意到,它们不遵循JavaScript对象的命名约定。我故意这样做,以便在客户端上完成与MVC的映射时,MVC在将它们映射到C#对象时不会出现问题。
从长远来看,这可能不是一件好事,但是为了简单起见,它会做到。
因此,基本上发生的是,当我们的DriversViewModel从服务器请求项目时,它将所有数据映射到Knockout友好的抽象中,随着Knockout的更改而对其进行跟踪。剩下的就是实际上告诉Knockout使用此ViewModel:
ko.applyBindings(new DriversViewModel());
现在敲除已准备就绪,可以使用这些对象了,现在是时候构建UI部件了。
使用这些KO绑定的页面如下所示:
<div>
<a href="#" data-bind="click: $root.addDriver">Add Driver</a>
<a href="#" data-bind="click: $root.update">Update</a>
</div>
<ul data-bind="foreach: Drivers, visible: Drivers().length > 0">
<ul>
<div>
<input data-bind="value: FullName"/>
<a href="#" data-bind="click: $parent.removeDriver">Delete</a>
<a href="#" data-bind="click: addCar">Add Car</a>
</div>
<ul class="no-cars" data-bind="visible: Cars().length == 0">No cars D:</ul>
<ul data-bind="foreach: Cars, visible: Cars().length > 0">
<li>
<div>
<a href="#" data-bind="click: $parent.removeCar">Delete</a>
<label>Car Name:</label> <input data-bind="value: Name"/>
<label>Car Code:</label> <input data-bind="value: Code"/>
</div>
</li>
</ul>
</ul>
</ul>
如您所见,没有什么棘手的问题。关于这一切的最棘手的部分是知道要使用哪个数据绑定指令,并跟踪在哪个上下文中实际使用哪个ViewModel。 (当您使用在不同ViewModel上定义的不同添加/删除功能时,这一点很重要。)
就是这样。这是一个很好的解决方案屏幕截图:
虽然看起来很凌乱,但可以完成工作。
单击相应的“添加”按钮时,会添加汽车或驾驶员。
单击“更新”按钮将组装整个树并将其重新发布到服务器,在此通过ASP.NET MVC magic的功能将其转换为POCO。
这是代码的binsbin,因此您可以复制粘贴并自己查看。您将不得不花一些时间在MVC项目上,但是我相信您可以解决这个问题。
页:
http://pastebin.com/2aGkEHEN
控制器:
http://pastebin.com/nZaufcpw
重要说明:
如果您确实想执行类似的操作,则可能需要跟踪用户如何更改数据,而不是仅获取整个更改后的结构并覆盖旧数据。
而不是在示例中向您展示的简单方法,我将尝试跟踪用户对树所做的更改,然后将某种更改集(而不是整个结构)发送到服务器。这样,您可以在事务中应用变更集并获得相同的结果,但带宽更少,一致性更高。
关于c# - 使用ASP.MVC编辑树状结构,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35283132/