премия
Прошло некоторое время, и у меня все еще есть пара нерешенных вопросов. Надеюсь, добавив награду, возможно, на эти вопросы будут даны ответы.
- Как использовать html-помощники с knockout.js
Почему документ был готов, чтобы он работал (дополнительную информацию см. В разделе «Первое редактирование»)
Как мне сделать что-то подобное, если я использую отображение нокаута с моими моделями представления? Поскольку у меня нет функции из-за маппинга.
function AppViewModel() { // ... leave firstName, lastName, and fullName unchanged here ... this.capitalizeLastName = function() { var currentVal = this.lastName(); // Read the current value this.lastName(currentVal.toUpperCase()); // Write back a modified value };
Я хочу использовать плагины, например, я хочу иметь возможность откатывать наблюдаемые, как если бы пользователь отменял запрос, я хочу иметь возможность вернуться к последнему значению. Судя по моим исследованиям, похоже, что люди создают плагины вроде editables.
Как мне использовать что-то подобное, если я использую отображение? Я действительно не хочу переходить к методу, в котором у меня есть ручное сопоставление в моем представлении, если бы я сопоставлял каждое поле MVC viewMode с полем модели KO, поскольку я хочу как можно меньше встроенного javascript, и это похоже на двойную работу, и это почему мне нравится это отображение.
Я обеспокоен тем, что для облегчения этой работы (с помощью сопоставления) я потеряю много KO-мощности, но, с другой стороны, я обеспокоен тем, что ручное сопоставление будет просто большой работой и приведет к тому, что мои представления будут содержать слишком много информации и может стать труднее поддерживать в будущем (скажем, если я удалю свойство в модели MVC, мне придется переместить его также в модель просмотра KO)
Исходный пост
Я использую asp.net mvc 3, и я изучаю нокаут, так как он выглядит довольно круто, но мне сложно понять, как он работает с asp.net mvc, особенно с моделями просмотра.
Для меня сейчас я делаю что-то вроде этого
public class CourseVM
{
public int CourseId { get; set; }
[Required(ErrorMessage = "Course name is required")]
[StringLength(40, ErrorMessage = "Course name cannot be this long.")]
public string CourseName{ get; set; }
public List<StudentVm> StudentViewModels { get; set; }
}
У меня был бы Vm с некоторыми основными свойствами, такими как CourseName, и поверх него была бы простая проверка. При необходимости модель Vm может содержать и другие модели представлений.
Затем я передал бы эту виртуальную машину в представление, где бы я использовал помощники html, чтобы помочь мне отобразить ее пользователю.
@Html.TextBoxFor(x => x.CourseName)
У меня может быть несколько циклов foreach или что-то еще, чтобы получить данные из коллекции моделей представления учеников.
Затем, когда я отправлял форму, я бы использовал jquery и serialize array
отправлял его методу действия контроллера, который привязывал бы его обратно к модели просмотра.
С knockout.js все по-другому, так как теперь у вас есть модели просмотра для него, и из всех примеров, которые я видел, они не используют помощники html.
Как вы используете эти две функции MVC с knockout.js?
Я нашел это видео, и оно вкратце (последние несколько минут видео в 18:48) описывает способ использования моделей просмотра, в основном имея встроенный скрипт с моделью просмотра knockout.js, которой присваиваются значения в ViewModel.
Это единственный способ сделать это? Как насчет моего примера с набором моделей просмотра? Должен ли я иметь цикл foreach или что-то в этом роде, чтобы извлечь все значения и назначить их для нокаута?
Что касается хелперов html, то видео о них ничего не говорит.
Это две области, которые меня чертовски смущают, поскольку, кажется, не так много людей говорят об этом, и это оставляет меня в замешательстве относительно того, как исходные значения и все остальное попадают в представление, когда когда-либо пример - это просто какой-то жестко закодированный пример значения.
редактировать
Я пробую то, что предложил Дарин Димитров, и, похоже, это работает (хотя мне пришлось внести некоторые изменения в его код). Не уверен, почему мне пришлось использовать готовый документ, но почему-то без него все было не готово.
@model MvcApplication1.Models.Test
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<title>Index</title>
<script src="../../Scripts/jquery-1.5.1.js" type="text/javascript"></script>
<script src="../../Scripts/knockout-2.1.0.js" type="text/javascript"></script>
<script src="../../Scripts/knockout.mapping-latest.js" type="text/javascript"></script>
<script type="text/javascript">
$(function()
{
var model = @Html.Raw(Json.Encode(Model));
// Activates knockout.js
ko.applyBindings(model);
});
</script>
</head>
<body>
<div>
<p>First name: <strong data-bind="text: FirstName"></strong></p>
<p>Last name: <strong data-bind="text: LastName"></strong></p>
@Model.FirstName , @Model.LastName
</div>
</body>
</html>
Мне пришлось обернуть его вокруг документа jquery, готового заставить его работать.
Я тоже получаю это предупреждение. Не уверен, о чем идет речь.
Warning 1 Conditional compilation is turned off -> @Html.Raw
Так что у меня есть отправная точка, я думаю, по крайней мере, обновлю, когда я еще немного поиграю и как это работает.
Я пытаюсь пройти интерактивные учебные пособия, но вместо этого использую ViewModel.
Пока не знаю, как справиться с этими частями
function AppViewModel() {
this.firstName = ko.observable("Bert");
this.lastName = ko.observable("Bertington");
}
или
function AppViewModel() {
// ... leave firstName, lastName, and fullName unchanged here ...
this.capitalizeLastName = function() {
var currentVal = this.lastName(); // Read the current value
this.lastName(currentVal.toUpperCase()); // Write back a modified value
};
Редактировать 2
Я смог разобраться с первой проблемой. Не имею ни малейшего понятия о второй проблеме. Тем не менее. У кого-нибудь есть идеи?
@model MvcApplication1.Models.Test
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<title>Index</title>
<script src="../../Scripts/jquery-1.5.1.js" type="text/javascript"></script>
<script src="../../Scripts/knockout-2.1.0.js" type="text/javascript"></script>
<script src="../../Scripts/knockout.mapping-latest.js" type="text/javascript"></script>
<script type="text/javascript">
$(function()
{
var model = @Html.Raw(Json.Encode(Model));
var viewModel = ko.mapping.fromJS(model);
ko.applyBindings(viewModel);
});
</script>
</head>
<body>
<div>
@*grab values from the view model directly*@
<p>First name: <strong data-bind="text: FirstName"></strong></p>
<p>Last name: <strong data-bind="text: LastName"></strong></p>
@*grab values from my second view model that I made*@
<p>SomeOtherValue <strong data-bind="text: Test2.SomeOtherValue"></strong></p>
<p>Another <strong data-bind="text: Test2.Another"></strong></p>
@*allow changes to all the values that should be then sync the above values.*@
<p>First name: <input data-bind="value: FirstName" /></p>
<p>Last name: <input data-bind="value: LastName" /></p>
<p>SomeOtherValue <input data-bind="value: Test2.SomeOtherValue" /></p>
<p>Another <input data-bind="value: Test2.Another" /></p>
@* seeing if I can do it with p tags and see if they all update.*@
<p data-bind="foreach: Test3">
<strong data-bind="text: Test3Value"></strong>
</p>
@*took my 3rd view model that is in a collection and output all values as a textbox*@
<table>
<thead><tr>
<th>Test3</th>
</tr></thead>
<tbody data-bind="foreach: Test3">
<tr>
<td>
<strong data-bind="text: Test3Value"></strong>
<input type="text" data-bind="value: Test3Value"/>
</td>
</tr>
</tbody>
</table>
контроллер
public ActionResult Index()
{
Test2 test2 = new Test2
{
Another = "test",
SomeOtherValue = "test2"
};
Test vm = new Test
{
FirstName = "Bob",
LastName = "N/A",
Test2 = test2,
};
for (int i = 0; i < 10; i++)
{
Test3 test3 = new Test3
{
Test3Value = i.ToString()
};
vm.Test3.Add(test3);
}
return View(vm);
}