Hojność
Minęło trochę czasu, a ja wciąż mam kilka nierozstrzygniętych pytań. Mam nadzieję, że przez dodanie nagrody może uzyskasz odpowiedzi na te pytania.
- Jak używać pomocników HTML w knockout.js
Dlaczego dokument był potrzebny, aby działał (zobacz pierwszą edycję, aby uzyskać więcej informacji)
Jak mogę zrobić coś takiego, jeśli używam mapowania wybicia w moich modelach widoku? Ponieważ nie mam funkcji ze względu na mapowanie.
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 };
Chcę na przykład używać wtyczek. Chcę mieć możliwość wycofania obserwowalnych, tak jakby użytkownik anulował żądanie. Chcę mieć możliwość powrotu do ostatniej wartości. Z moich badań wynika, że osiągają to ludzie tworzący wtyczki, takie jak elementy do edycji
Jak użyć czegoś takiego, jeśli używam mapowania? Naprawdę nie chcę przechodzić do metody, w której mam w widoku mapowanie ręczne, w którym mapuję każde pole MVC viewMode na pole modelu KO, tak jak chcę, jak najmniej wbudowanego javascript, a to wydaje się po prostu podwoić pracę i to jest dlaczego lubię to mapowanie.
Obawiam się, że aby ułatwić tę pracę (używając mapowania) stracę dużo mocy KO, ale z drugiej strony obawiam się, że ręczne mapowanie będzie po prostu dużo pracy i sprawi, że moje widoki będą zawierały zbyt dużo informacji i w przyszłości może stać się trudniejsze w utrzymaniu (powiedzmy, że jeśli usunę właściwość w modelu MVC, muszę ją przenieść również w modelu widoku KO)
Oryginalny post
Używam asp.net mvc 3 i patrzę na nokaut, ponieważ wygląda całkiem fajnie, ale mam trudności z ustaleniem, jak to działa z asp.net mvc, zwłaszcza widok modeli.
Dla mnie teraz robię coś takiego
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; }
}
Chciałbym mieć maszynę wirtualną, która ma kilka podstawowych właściwości, takich jak CourseName, i będzie miała kilka prostych walidacji. W razie potrzeby model Vm może również zawierać inne modele widoków.
Następnie przekazałbym to Vm do widoku, w którym użyłbym pomocników HTML, aby pomóc mi wyświetlić go użytkownikowi.
@Html.TextBoxFor(x => x.CourseName)
Mogę mieć jakieś pętle foreach lub coś do pobrania danych z kolekcji modeli widoku ucznia.
Następnie, serialize array
wysyłając formularz, użyłbym jquery i wysłałbym go do metody akcji kontrolera, która wiązałaby go z powrotem z viewmodelem.
Z knockout.js jest inaczej, ponieważ masz teraz modele widoku i ze wszystkich przykładów, które widziałem, nie używają pomocników HTML.
Jak wykorzystać te dwie funkcje MVC w knockout.js?
Znalazłem ten film i na krótko (ostatnie kilka minut filmu @ 18:48) omawia sposób korzystania z modeli widoków, zasadniczo mając wbudowany skrypt, który ma model widoku knockout.js, któremu przypisywane są wartości w modelu ViewModel.
Czy to jedyny sposób, aby to zrobić? A co z moim przykładem z kolekcją modeli widoku? Czy muszę mieć pętlę foreach czy coś, aby wyodrębnić wszystkie wartości i przypisać je do nokautu?
Jeśli chodzi o pomocników HTML, wideo nic o nich nie mówi.
To są 2 obszary, które mnie mylą, ponieważ niewiele osób wydaje się o tym mówić, a to sprawia, że jestem zdezorientowany, w jaki sposób początkowe wartości i wszystko docierają do punktu widzenia, kiedy przykład jest tylko jakimś zakodowanym przykładem wartości.
Edytować
Próbuję tego, co zasugerował Darin Dimitrov i wydaje się, że działa (musiałem jednak wprowadzić pewne zmiany w jego kodzie). Nie jestem pewien, dlaczego musiałem użyć gotowego dokumentu, ale jakoś bez niego wszystko nie było gotowe.
@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>
Musiałem owinąć go wokół dokumentu jQuery, gotowego do działania.
Otrzymuję również to ostrzeżenie. Nie wiem, o co w tym wszystkim chodzi.
Warning 1 Conditional compilation is turned off -> @Html.Raw
Mam więc punkt wyjścia, który przynajmniej się zaktualizuje, kiedy zrobię więcej zabawy i jak to działa.
Próbuję przejść przez interaktywne samouczki, ale zamiast tego używam ViewModel.
Nie wiem jeszcze, jak sobie z tym poradzić
function AppViewModel() {
this.firstName = ko.observable("Bert");
this.lastName = ko.observable("Bertington");
}
lub
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
};
Edytuj 2
Udało mi się rozwiązać pierwszy problem. Nie mam pojęcia o drugim problemie. A jednak. Czy ktoś ma jakieś pomysły?
@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>
Kontroler
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);
}