我正在尝试在我的一个剃刀视图上集成ko。我昨天研究了很多但是找不到针对我的问题的类似解决方案。
我有一个记录模型:
Foldable
一个人模型:
public class Record
{
public Int Request Id {get;set;}
public string RecordName {get;set;}
public Person Person {get;set;}
public IList<Person> People { get; set; }
}
我的观点:
public class Person
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public IList<Alias> Aliases { get; set; }
}
}
和脚本:
@model Record
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
@using (Html.BeginForm("PostRequest", "Request", FormMethod.Post))
{
@Html.LabelFor(m => m.Person.FirstName)
@Html.TextBoxFor(m => m.Person.FirstName)
<h5>People</h5>
<table>
<tbody data-bind="foreach: People">
<tr>
<td>@Html.LabelFor(m => m.Person.FirstName)</td>
<td><input type="text" data-bind="value: FirstName, attr: {name: 'People[' + $index() + '].FirstName'}" /></td>
<td>@Html.LabelFor(m => m.Person.LastName)</td>
<td><input type="text" data-bind="value: LastName, attr: {name: 'People[' + $index() + '].LastName'}" /></td>
</tr>
<tr>
<td><button id="removePerson" data-bind="click: $root.removePerson">Remove Person</button></td>
</tr>
<tr>
<td>
<button id="addAlias" data-bind="click: addAlias">Add Alias</button>
</td>
</tr>
<!-- ko foreach: Aliases -->
<tr>
<td>@Html.LabelFor(m => m.Alias.FirstNameAlias)</td>
<td><input type="text" data-bind="value: FirstNameAlias, attr: {name: 'Aliases[' + $index() + '].FirstNameAlias'}" /></td>
<td>@Html.LabelFor(m => m.Alias.LastNameAlias)</td>
<td><input type="text" data-bind="value: LastNameAlias, attr: {name: 'Aliases[' + $index() + '].LastNameAlias'}" /></td>
<td><button id="removeAlias" data-bind="click: $root.removeAlias">Remove Alias</button></td>
</tr>
<!-- /ko -->
</tbody>
</table>
<button id="addPerson" data-bind="click: addPerson">Add Person</button>
<button>Submit</button>
<input id="clickMe" type="button" value="clickme" onclick="submit();" />
获取此视图的Controller操作会初始化记录模型的某些数据,因此绑定似乎正常工作,但是当我发布数据时,Alias List的数据将返回Null。
控制器:
@section scripts
{
<script type="text/javascript">
$(function () {
var personItem = function () {
var self = this;
self.LastName = ko.observable();
self.FirstName = ko.observable();
self.Aliases = ko.observableArray();
};
var model = ko.mapping.fromJS(@Html.Raw(Model.ToJson()));
alert('The length of the array is ' + model.People().length);
alert('The first element is ' + model.People()[0].Aliases().length);
alert(ko.toJSON(model));
model.addPerson = function () {
model.People.push(new personItem());
};
model.removePerson = function (person) {
model.People.remove(person);
};
ko.applyBindings(model);
})
function submit() {
$.ajax({
url: '/Request/PostRequest',
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: ko.toJSON(model),
success: function (status) {
alert(status);
}
});
};
</script>
}
我觉得我错过了ko.mapping的东西。但是如此接近,因为数据从GET控制器操作填充,但无法POST。
解
我更新了我的KO脚本,以及我在视图中呈现ko数据的方式。这解决了我的问题。
更新了脚本
public ActionResult CreateRequest(Record viewModel)
{
var list = new Record
{
People = new List<Person> {
new Person {FirstName = "My First Person", Aliases = new List<Alias> { new Alias{FirstNameAlias = "firstnamealias",LastNameAlias = "lastnamealias1"}},},
new Person {FirstName = "My Second Person", Aliases = new List<Alias> { new Alias{FirstNameAlias = "firstnamealias2", LastNameAlias ="lastnamealias2"}},}
},
Person = new Person()
{
FirstName = "me"
}
};
return View(list);
}
[HttpPost]
public JsonResult PostRequest(Record viewModel)
{
return Json(String.Format("'Success':'false','Error':'"));
}
更新了视图
<script>
var initialData = @Html.Raw(Serialize(Model.People));
var BackgroundModel = function(people) {
var self = this;
self.people = ko.mapping.fromJS(people);
self.addPerson = function() {
self.people.push({
FirstName: "",
LastName: "",
Aliases: ko.observableArray()
});
};
self.removePerson = function(person) {
self.people.remove(person);
};
self.addAlias = function(person) {
person.Aliases.push({
//todo
FirstNameAlias: "",
LastNameAlias: ""
});
};
self.removeAlias = function(Alias) {
$.each(self.people(), function() { this.Aliases.remove(Alias) })
};
self.save = function() {
self.lastSavedJson(JSON.stringify(ko.toJS(self.people), null, 2));
var subModel = JSON.stringify(ko.toJS(self));
$.ajax({
url: '/Request/PostRequest',
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: subModel,
success: function (status) {
alert(status);
}
});
};
self.lastSavedJson = ko.observable("")
};
ko.applyBindings(new BackgroundModel(initialData));
</script>
答案 0 :(得分:2)
提交功能中的变量model
将是undefined
,而不是您期望它的模型。
将提交方法移至您的模型中......
$(function () {
var personItem = function () {
var self = this;
self.LastName = ko.observable();
self.FirstName = ko.observable();
self.Aliases = ko.observableArray();
};
var model = ko.mapping.fromJS(@Html.Raw(Model.ToJson()));
alert('The length of the array is ' + model.People().length);
alert('The first element is ' + model.People()[0].Aliases().length);
alert(ko.toJSON(model));
model.addPerson = function () {
model.People().push(new personItem());
};
model.removePerson = function (person) {
model.People().remove(person);
};
model.submit = function() {
$.ajax({
url: '/Request/PostRequest',
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: ko.toJSON(model),
success: function (status) {
alert(status);
}
});
};
ko.applyBindings(model);
});
并将按钮上的绑定更新为
<input id="clickMe" type="button" value="clickme" data-bind="click: submit" />
同时强>
Controller.Json
期望对象序列化而不是字符串
[HttpPost]
public JsonResult PostRequest(Record viewModel)
{
return Json(String.Format("'Success':'false','Error':'"));
}
应该是:
[HttpPost]
public JsonResult PostRequest(Record viewModel)
{
return Json(new { success = false, error: String.Empty });
}
<强>更新强>
还注意到更新model.People数组的另一个问题
model.addPerson = function () {
model.People.push(new personItem());
};
model.removePerson = function (person) {
model.People.remove(person);
};
在这些函数中,model.People
应为model.People()
,即
model.addPerson = function () {
model.People().push(new personItem());
};
model.removePerson = function (person) {
model.People().remove(person);
};
注意模型之后的()
。人 - 包含在上面的代码块中。