我想我已经总结了您所有的问题,如果我遗漏了什么,请告诉我(如果您可以将所有问题总结在一个地方就好了 =))
笔记。兼容性ko.editable
已添加插件
Download完整代码
如何将 html 助手与 knockout.js 一起使用
这很容易:
@Html.TextBoxFor(model => model.CourseId, new { data_bind = "value: CourseId" })
Where:
-
value: CourseId
表明您正在绑定value
的财产input
控制与CourseId
来自您的模型和脚本模型的属性
结果是:
<input data-bind="value: CourseId" data-val="true" data-val-number="The field CourseId must be a number." data-val-required="The CourseId field is required." id="CourseId" name="CourseId" type="text" value="12" />
为什么需要准备好文档才能使其正常工作(有关更多信息,请参阅第一次编辑)
我还不明白为什么你需要使用ready
序列化模型的事件,但似乎很简单required(不过不用担心)
如果我在视图模型中使用剔除映射,我该如何做这样的事情?因为我没有映射的功能。
如果我理解正确的话,你需要向 KO 模型附加一个新方法,这很容易合并模型
有关更多信息,请参阅“来自不同来源的映射”部分
function viewModel() {
this.addStudent = function () {
alert("de");
};
};
$(function () {
var jsonModel = '@Html.Raw(JsonConvert.SerializeObject(this.Model))';
var mvcModel = ko.mapping.fromJSON(jsonModel);
var myViewModel = new viewModel();
var g = ko.mapping.fromJS(myViewModel, mvcModel);
ko.applyBindings(g);
});
关于您收到的警告
警告 1 条件编译已关闭 -> @Html.Raw
您需要使用引号
与 ko.editable 插件的兼容性
我以为它会更复杂,但事实证明集成非常简单,为了使您的模型可编辑,只需添加以下行:(请记住,在这种情况下,我使用的是混合模型,来自服务器和在客户端中添加扩展并且可编辑功能很简单......这很棒):
ko.editable(g);
ko.applyBindings(g);
从这里你只需要play例如,使用插件添加的扩展进行绑定,我有一个按钮可以开始像这样编辑我的字段,在这个按钮中我开始编辑过程:
this.editMode = function () {
this.isInEditMode(!this.isInEditMode());
this.beginEdit();
};
然后我有提交和取消按钮,代码如下:
this.executeCommit = function () {
this.commit();
this.isInEditMode(false);
};
this.executeRollback = function () {
if (this.hasChanges()) {
if (confirm("Are you sure you want to discard the changes?")) {
this.rollback();
this.isInEditMode(false);
}
}
else {
this.rollback();
this.isInEditMode(false);
}
};
最后,我有一个字段来指示字段是否处于编辑模式,这只是为了绑定启用属性。
this.isInEditMode = ko.observable(false);
关于你的数组问题
我可能有一些 foreach 循环或其他东西来从学生视图模型集合中获取数据。
然后,当我提交表单时,我将使用 jquery 并序列化数组,并将其发送到控制器操作方法,该方法将其绑定回视图模型。
您可以对 KO 执行相同的操作,在下面的示例中,我将创建以下输出:
基本上在这里,您有两个列表,使用创建Helpers
并与 KO 结合,他们有dblClick
事件绑定,当触发时,从当前列表中删除所选项目并将其添加到其他列表中,当您发布到Controller
,每个列表的内容作为 JSON 数据发送并重新附加到服务器模型
Nuggets:
外部的scripts.
控制器代码
[HttpGet]
public ActionResult Index()
{
var m = new CourseVM { CourseId = 12, CourseName = ".Net" };
m.StudentViewModels.Add(new StudentVm { ID = 545, Name = "Name from server", Lastname = "last name from server" });
return View(m);
}
[HttpPost]
public ActionResult Index(CourseVM model)
{
if (!string.IsNullOrWhiteSpace(model.StudentsSerialized))
{
model.StudentViewModels = JsonConvert.DeserializeObject<List<StudentVm>>(model.StudentsSerialized);
model.StudentsSerialized = string.Empty;
}
if (!string.IsNullOrWhiteSpace(model.SelectedStudentsSerialized))
{
model.SelectedStudents = JsonConvert.DeserializeObject<List<StudentVm>>(model.SelectedStudentsSerialized);
model.SelectedStudentsSerialized = string.Empty;
}
return View(model);
}
Model
public class CourseVM
{
public CourseVM()
{
this.StudentViewModels = new List<StudentVm>();
this.SelectedStudents = new List<StudentVm>();
}
public int CourseId { get; set; }
[Required(ErrorMessage = "Course name is required")]
[StringLength(100, ErrorMessage = "Course name cannot be this long.")]
public string CourseName { get; set; }
public List<StudentVm> StudentViewModels { get; set; }
public List<StudentVm> SelectedStudents { get; set; }
public string StudentsSerialized { get; set; }
public string SelectedStudentsSerialized { get; set; }
}
public class StudentVm
{
public int ID { get; set; }
public string Name { get; set; }
public string Lastname { get; set; }
}
CSHTML页面
@using (Html.BeginForm())
{
@Html.ValidationSummary(true)
<fieldset>
<legend>CourseVM</legend>
<div>
<div class="editor-label">
@Html.LabelFor(model => model.CourseId)
</div>
<div class="editor-field">
@Html.TextBoxFor(model => model.CourseId, new { data_bind = "enable: isInEditMode, value: CourseId" })
@Html.ValidationMessageFor(model => model.CourseId)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.CourseName)
</div>
<div class="editor-field">
@Html.TextBoxFor(model => model.CourseName, new { data_bind = "enable: isInEditMode, value: CourseName" })
@Html.ValidationMessageFor(model => model.CourseName)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.StudentViewModels);
</div>
<div class="editor-field">
@Html.ListBoxFor(
model => model.StudentViewModels,
new SelectList(this.Model.StudentViewModels, "ID", "Name"),
new
{
style = "width: 37%;",
data_bind = "enable: isInEditMode, options: StudentViewModels, optionsText: 'Name', value: leftStudentSelected, event: { dblclick: moveFromLeftToRight }"
}
)
@Html.ListBoxFor(
model => model.SelectedStudents,
new SelectList(this.Model.SelectedStudents, "ID", "Name"),
new
{
style = "width: 37%;",
data_bind = "enable: isInEditMode, options: SelectedStudents, optionsText: 'Name', value: rightStudentSelected, event: { dblclick: moveFromRightToLeft }"
}
)
</div>
@Html.HiddenFor(model => model.CourseId, new { data_bind="value: CourseId" })
@Html.HiddenFor(model => model.CourseName, new { data_bind="value: CourseName" })
@Html.HiddenFor(model => model.StudentsSerialized, new { data_bind = "value: StudentsSerialized" })
@Html.HiddenFor(model => model.SelectedStudentsSerialized, new { data_bind = "value: SelectedStudentsSerialized" })
</div>
<p>
<input type="submit" value="Save" data-bind="enable: !isInEditMode()" />
<button data-bind="enable: !isInEditMode(), click: editMode">Edit mode</button><br />
<div>
<button data-bind="enable: isInEditMode, click: addStudent">Add Student</button>
<button data-bind="enable: hasChanges, click: executeCommit">Commit</button>
<button data-bind="enable: isInEditMode, click: executeRollback">Cancel</button>
</div>
</p>
</fieldset>
}
Scripts
<script src="@Url.Content("~/Scripts/jquery-1.7.2.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/knockout-2.1.0.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/knockout.mapping-latest.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/ko.editables.js")" type="text/javascript"></script>
<script type="text/javascript">
var g = null;
function ViewModel() {
this.addStudent = function () {
this.StudentViewModels.push(new Student(25, "my name" + new Date(), "my last name"));
this.serializeLists();
};
this.serializeLists = function () {
this.StudentsSerialized(ko.toJSON(this.StudentViewModels));
this.SelectedStudentsSerialized(ko.toJSON(this.SelectedStudents));
};
this.leftStudentSelected = ko.observable();
this.rightStudentSelected = ko.observable();
this.moveFromLeftToRight = function () {
this.SelectedStudents.push(this.leftStudentSelected());
this.StudentViewModels.remove(this.leftStudentSelected());
this.serializeLists();
};
this.moveFromRightToLeft = function () {
this.StudentViewModels.push(this.rightStudentSelected());
this.SelectedStudents.remove(this.rightStudentSelected());
this.serializeLists();
};
this.isInEditMode = ko.observable(false);
this.executeCommit = function () {
this.commit();
this.isInEditMode(false);
};
this.executeRollback = function () {
if (this.hasChanges()) {
if (confirm("Are you sure you want to discard the changes?")) {
this.rollback();
this.isInEditMode(false);
}
}
else {
this.rollback();
this.isInEditMode(false);
}
};
this.editMode = function () {
this.isInEditMode(!this.isInEditMode());
this.beginEdit();
};
}
function Student(id, name, lastName) {
this.ID = id;
this.Name = name;
this.LastName = lastName;
}
$(function () {
var jsonModel = '@Html.Raw(JsonConvert.SerializeObject(this.Model))';
var mvcModel = ko.mapping.fromJSON(jsonModel);
var myViewModel = new ViewModel();
g = ko.mapping.fromJS(myViewModel, mvcModel);
g.StudentsSerialized(ko.toJSON(g.StudentViewModels));
g.SelectedStudentsSerialized(ko.toJSON(g.SelectedStudents));
ko.editable(g);
ko.applyBindings(g);
});
</script>
注意:我刚刚添加了这些行:
@Html.HiddenFor(model => model.CourseId, new { data_bind="value: CourseId" })
@Html.HiddenFor(model => model.CourseName, new { data_bind="value: CourseName" })
因为当我提交表单时,我的字段被禁用,因此值没有传输到服务器,这就是为什么我添加了几个隐藏字段来实现这一点