Ответ 1
Я думаю, что я обобщил все ваши вопросы, если я пропустил что-то, пожалуйста, дайте мне знать (если бы вы могли суммировать все ваши вопросы в одном месте, было бы хорошо =))
Примечание. Совместимость с добавленным плагином ko.editable
Загрузить полный код
Как вы используете html-помощники с knockout.js
Это легко:
@Html.TextBoxFor(model => model.CourseId, new { data_bind = "value: CourseId" })
Где:
-
value: CourseId
указывает, что вы привязываете свойствоvalue
элемента управленияinput
с свойствомCourseId
от вашей модели и вашей модели script
Результат:
<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
для сериализации модели, но кажется, что это просто требуется (не беспокоиться об этом, хотя)
Как мне сделать что-то подобное, если я использую сопоставление нокаутов с моими моделями просмотров? Поскольку у меня нет функции из-за отображения.
Если я правильно понял, вам нужно добавить новый метод к модели 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);
Отсюда вам просто нужно играть со своими привязками, используя расширения, добавленные плагином, например, у меня есть кнопка, чтобы начать редактировать мои поля, как это, и в этой кнопке я запускаю процесс редактирования:
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);
}
};
И, наконец, у меня есть одно поле, указывающее, находятся ли поля в режиме редактирования или нет, это просто привязать свойство enable.
this.isInEditMode = ko.observable(false);
О задании массива
У меня могут быть некоторые петли foreach или что-то, чтобы получить данные из коллекции моделей просмотра учащихся.
Затем, когда я отправлю форму, я буду использовать jquery и сериализуем массив и отправить его методу действия контроллера, который привяжет его к viewmodel.
Вы можете сделать то же самое с KO, в следующем примере я создам следующий вывод:
В принципе, у вас есть два списка, созданные с помощью Helpers
и привязанные к KO, у них есть связанное событие dblClick
, которое при запуске удаляет выбранный элемент из текущего списка и добавляет его в другой список, когда вы отправляете сообщение в Controller
, содержимое каждого списка отправляется как данные JSON и повторно привязывается к модели сервера
Nuggets:
Внешний скрипты.
Код контроллера
[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>
}
Сценарии
<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" })
Потому что, когда я отправляю форму, мои поля отключены, поэтому значения не были переданы на сервер, поэтому я добавил пару скрытых полей, чтобы сделать трюк