Generosidad
Ha pasado un tiempo y todavía tengo un par de preguntas pendientes. Espero que al agregar una recompensa, tal vez estas preguntas sean respondidas.
- ¿Cómo se usan los ayudantes html con knockout.js?
¿Por qué se necesitaba un documento listo para que funcione? (Ver primera edición para más información)
¿Cómo hago algo como esto si estoy usando el mapeo knockout con mis modelos de vista? Como no tengo una función debido a la asignación.
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 };
Quiero usar complementos, por ejemplo, quiero poder revertir los observables como si un usuario cancela una solicitud Quiero poder volver al último valor. Según mi investigación, esto parece ser logrado por personas que crean complementos como editables
¿Cómo uso algo así si estoy usando mapeo? Realmente no quiero ir a un método en el que tengo en mi vista mapeo manual donde mapeo cada campo MVC viewMode a un campo modelo KO, ya que quiero el menor javascript en línea posible y eso parece el doble de trabajo y eso es Por eso me gusta ese mapeo.
Me preocupa que para facilitar el trabajo (mediante el mapeo) pierda una gran cantidad de KO pero, por otro lado, me preocupa que el mapeo manual sea mucho trabajo y haga que mis vistas contengan demasiada información y en el futuro podría ser más difícil de mantener (por ejemplo, si elimino una propiedad en el modelo MVC, también tengo que moverla en el modelo de vista KO)
Publicación original
Estoy usando asp.net mvc 3 y estoy investigando la eliminación, ya que se ve muy bien, pero me está costando descubrir cómo funciona con asp.net mvc, especialmente ver modelos.
Para mí en este momento hago algo como esto
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; }
}
Tendría un Vm que tiene algunas propiedades básicas como CourseName y tendrá una validación simple encima. El modelo Vm también puede contener otros modelos de vista si es necesario.
Luego pasaría este Vm a la Vista donde usaría los ayudantes html para ayudarme a mostrarlo al usuario.
@Html.TextBoxFor(x => x.CourseName)
Es posible que tenga algunos bucles foreach o algo para obtener los datos de la colección de Modelos de vista de estudiante.
Luego, cuando envíe el formulario, usaría jquery y lo serialize array
enviaría a un método de acción del controlador que lo vincularía de nuevo al modelo de vista.
Con knockout.js todo es diferente, ya que ahora tiene modelos de vista para él y de todos los ejemplos que vi, no usan ayudantes html.
¿Cómo utiliza estas 2 características de MVC con knockout.js?
Encontré este video y brevemente (últimos minutos del video a las 18:48) sirve para usar modelos de vista básicamente teniendo un script en línea que tiene el modelo de vista knockout.js al que se le asignan los valores en ViewModel.
¿Es esta la única manera de hacerlo? ¿Qué tal en mi ejemplo con tener una colección de modelos de vista? ¿Tengo que tener un bucle foreach o algo para extraer todos los valores y asignarlo a knockout?
En cuanto a los ayudantes html, el video no dice nada sobre ellos.
Estas son las 2 áreas que me confunden muchísimo, ya que no muchas personas parecen hablar de eso y me deja confundido sobre cómo los valores iniciales y todo está llegando a la vista cuando algún ejemplo es solo un ejemplo de valor codificado.
Editar
Estoy intentando lo que ha sugerido Darin Dimitrov y esto parece funcionar (aunque tuve que hacer algunos cambios en su código). No estoy seguro de por qué tuve que usar el documento listo, pero de alguna manera no todo estaba listo sin él.
@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>
Tuve que envolverlo alrededor de un documento jquery listo para que funcione.
También recibo esta advertencia. No estoy seguro de qué se trata.
Warning 1 Conditional compilation is turned off -> @Html.Raw
Así que tengo un punto de partida, supongo que al menos se actualizará cuando haya jugado un poco más y cómo funciona.
Estoy tratando de seguir los tutoriales interactivos, pero en su lugar utilizo un ViewModel.
Aún no estoy seguro de cómo abordar estas partes
function AppViewModel() {
this.firstName = ko.observable("Bert");
this.lastName = ko.observable("Bertington");
}
o
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
};
Editar 2
Pude resolver el primer problema. No tengo idea del segundo problema. Sin embargo, sin embargo. ¿Alguien tiene alguna idea?
@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>
Controlador
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);
}