премия
Прошло некоторое время, и у меня все еще есть пара нерешенных вопросов. Надеюсь, добавив награду, возможно, на эти вопросы будут даны ответы.
- Как использовать 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);
}
Ответы:
Думаю, я обобщил все ваши вопросы, если я что-то пропустил, дайте мне знать ( если бы вы могли обобщить все ваши вопросы в одном месте, было бы неплохо =))
Заметка.
ko.editable
Добавлена совместимость с плагиномСкачать полный код
Как использовать html-помощники с knockout.js
Это просто:
Куда:
value: CourseId
указывает, что вы привязываетеvalue
свойство элементаinput
управления кCourseId
свойству из вашей модели и вашей модели сценарияРезультат:
Почему документ был готов, чтобы он работал (дополнительную информацию см. В разделе «Первое редактирование»)
Я пока не понимаю, почему вам нужно использовать
ready
событие для сериализации модели, но кажется, что это просто необходимо (хотя не беспокойтесь об этом)Как мне сделать что-то подобное, если я использую отображение нокаута с моими моделями представления? Поскольку у меня нет функции из-за маппинга.
Если я правильно понимаю, вам нужно добавить новый метод в модель KO, ну, это простое объединение моделей
Для получения дополнительной информации в разделе -Картирование из разных источников-
О предупреждении, которое вы получали
Вам нужно использовать кавычки
Совместимость с плагином ko.editable
Я думал, что это будет сложнее, но оказалось, что интеграция действительно проста, чтобы сделать вашу модель редактируемой, просто добавьте следующую строку: (помните, что в этом случае я использую смешанную модель с сервера и добавление расширения в клиенте, и редактируемый просто работает ... это здорово):
Отсюда вам просто нужно поиграть со своими привязками, используя расширения, добавленные подключаемым модулем, например, у меня есть кнопка для начала редактирования моих полей, как это, и с помощью этой кнопки я запускаю процесс редактирования:
Затем у меня есть кнопки фиксации и отмены со следующим кодом:
И, наконец, у меня есть одно поле, чтобы указать, находятся ли поля в режиме редактирования или нет, это просто для привязки свойства enable.
О вашем вопросе о массиве
Вы можете сделать то же самое с KO, в следующем примере я создам следующий вывод:
В основном здесь у вас есть два списка, созданные с использованием
Helpers
и привязанные к KO, у них естьdblClick
привязанное событие, которое при запуске удаляет выбранный элемент из текущего списка и добавляет его в другой список, когда вы публикуетеController
содержимое каждого список отправляется как данные JSON и повторно прикрепляется к модели сервераNuggets:
Внешние скрипты .
Код контроллера
Модель
Страница CSHTML
Сценарии
Примечание: я только что добавил эти строки:
Поскольку, когда я отправляю форму, мои поля отключены, поэтому значения не были переданы на сервер, поэтому я добавил пару скрытых полей, чтобы сделать трюк
источник
ko.editables
подключаемым модулем, вы можете проверить обновленный ответ или, если хотите, вы можете загрузить весь проект, чтобы запустить его локальноВы можете сериализовать свою модель представления ASP.NET MVC в переменную javascript:
В документации по выбиванию есть множество примеров, которые вы могли бы изучить.
источник
Чтобы получить дополнительные вычисляемые свойства после сопоставления сервера, вам нужно будет дополнительно улучшить свои модели просмотра на стороне клиента.
Например:
Поэтому каждый раз, когда вы сопоставляете необработанный JSON, вам нужно будет повторно применять вычисленные свойства.
Кроме того, подключаемый модуль сопоставления предоставляет возможность постепенно обновлять модель просмотра, а не воссоздавать ее каждый раз, когда вы переходите туда и обратно (используйте дополнительный параметр в
fromJS
):И это выполняет инкрементное обновление данных в вашей модели только сопоставленных свойств. Вы можете узнать больше об этом в документации по сопоставлению.
Вы упомянули в комментариях к ответу Дарина пакет FluentJSON . Я автор этого, но его вариант использования более конкретен, чем ko.mapping. Обычно я бы использовал его только в том случае, если ваши модели просмотра односторонние (например, сервер -> клиент), а затем данные отправляются обратно в каком-то другом формате (или не отправляются вообще). Или если ваша модель просмотра javascript должна быть в формате, существенно отличном от вашей модели сервера.
источник