9

Estoy comenzando un nuevo proyecto, y estoy dispuesto a utilizar KnockoutJS + Web Api que son nuevos para mí, tengo un buen conocimiento de Web Api, pero Knockout es difícil de entender en este momento.ASP.Net Web Api + KnockoutJs + MVC4 - Vincularlo

Ésta es mis pensamientos iniciales de cómo quiero que mi aplicación para trabajar:

  • que tienen un controlador estándar MVC como LeadsController
  • LeadsControllerAction tiene una llamada ListLeads, esto no vuelven en realidad cualquier datos, pero solo devuelve una vista con una plantilla para mostrar los datos de Knockout.
  • La vista ListLeads llama mi controlador de API LeadsApiController a través de AJAX para obtener una lista de clientes potenciales para mostrar
  • Los datos de clientes potenciales a continuación, se asigna a un modelo de vista KnockoutJs (no quiero replicar mis modelos de vista del lado del servidor en JavaScript ver modelos)
  • Quiero usar archivos JavaScript externos tanto como sea posible en lugar de hinchar mi página HTML llena de JavaScript.

He visto muchos ejemplos pero la mayoría de ellos devuelve algunos datos iniciales en la carga de la primera página, en lugar de a través de una llamada ajax.

Así que mi pregunta es, ¿cómo crearía mi JavaScript viewModel para Knockout cuando se recupera de ajax, donde se crea la URL ajax usando Url.Content().

Además, ¿qué sucede si necesito valores calculados adicionales en este ViewModel, cómo extendería el modelo de vista mapeada desde el lado del servidor.

Si no me he explicado bien, por favor avíseme de lo que no está seguro e intentaré actualizar mi pregunta para que sea más explícita.

Respuesta

4

Creo que su diseño es una buena idea. De hecho, ¡estoy desarrollando una aplicación usando exactamente este diseño ahora mismo!

No tiene que insertar los datos iniciales en su página. En cambio, cuando se carga la página, crean un modelo de vista vacía, llame ko.applyBindings, a continuación, iniciar una llamada AJAX que poblar el modelo de vista cuando se complete:

$(function() { 
    var viewModel = { 
     leads: ko.observableArray([]) // empty array for now 
    }; 

    ko.applyBindings(viewModel); 

    $.getJSON("/api/Leads", function (data) { 
     var newLeads = ko.mapping.fromJS(data)(); // convert to view model objects 
     viewModel.leads(newLeads); // replace the empty array with a populated one 
    }); 
}); 

Usted querrá poner un mensaje "Carga" en algún lugar en su página hasta que se complete la llamada AJAX.

para generar el "/ api/Leads" URL, utilice Url.RouteUrl: (. Eso suponiendo su ruta API configura en Global.asax o App_Start \ RouteConfig.cs se denomina "DefaultApi")

<script> 
    var apiUrl = '@Url.RouteUrl("DefaultApi", new { httproute = "", controller = "Leads" })'; 
</script> 

El complemento de mapeo de desactivación se usa arriba para convertir el resultado AJAX JSON en un modelo de vista eliminatoria. Por defecto, el modelo de vista generado tendrá una propiedad observable para cada propiedad en el JSON. Para personalizar esto, como para agregar propiedades calculadas adicionales, use el complemento "create" callback de la asignación de mapeo.

Después de llegar tan lejos en mi aplicación, descubrí que quería más metadatos de los modelos de vista del servidor disponibles para el código del lado del cliente, como qué propiedades son necesarias y qué validaciones hay en cada propiedad. En el mapeo "crear" devoluciones de llamada, quería esta información para generar automáticamente propiedades adicionales y observaciones observables en los modelos de visualización. Por lo tanto, en el lado del servidor, utilicé algunas clases de marcos MVC y reflexión para inspeccionar los modelos de vista y generar algunos metadatos como JavaScript que se incrusta en las vistas relevantes. En el lado del cliente, tengo archivos JavaScript externos que conectan las devoluciones de llamada de mapeo y generan modelos de vista de acuerdo con los metadatos provistos en la página. Mi consejo es comenzar escribiendo a mano las personalizaciones del modelo de visualización inactiva y otro JavaScript en cada vista, luego, a medida que refactoriza, mueva las funciones de JavaScript genéricas a archivos externos. Cada vista debe terminar con solo el JavaScript mínimo que es específico para esa vista, momento en el que puede considerar escribir C# para generar ese JavaScript a partir de las anotaciones del modelo de la vista del servidor.

+0

Hola Joe. Tu enfoque es absolutamente correcto y una gran cantidad de tutoriales/blogs que he estado viendo tienen una solución similar. He estado evaluando este enfoque para una gran aplicación web que estamos comenzando. Mi problema es escribir mucho de JS que considero que es difícil de manejar. ¿De qué sirve usar controladores MVC y WebAPI y por qué usar un controlador MVC para pasar una vista vacía? parece que está creando duplicidad. – Yashvit

+0

MCV devuelve el HTML estático para la página. La API web devuelve los datos JSON del modelo de vista para la página. Si no te gusta una vista "vacía" pero aún quieres utilizar Knockout, puedes serializar los datos del modelo de vista a JSON en el servidor e insertarlo en la vista HTML, siempre y cuando no quieras usar AJAX y no me importa que el HTML ya no sea almacenable en caché. –

+0

Hoy en día existen muchas soluciones para administrar grandes aplicaciones JS. En el año desde que escribí esta respuesta, ahora tenemos Breeze.js y Durandal para organizar todo e implementar la plomería. Vea el proyecto de demostración BreeHe's TempHire. –

1

Para el tema url agregar esto en su _Layout.cshtml en un lugar en el que está delante de los archivos que se van a utilizar:

<script> 
    window._appRootUrl = '@Url.Content("~/")'; 
</script> 

continuación, puede utilizar la window._appRootUrl para componer las URL con la concatenación de cadenas o con la ayuda de una biblioteca de JavaScript como URI.js.

En cuanto a los valores calculados adicionales, es posible que desee utilizar un observable calculado knockout. Si eso no es posible o prefiere hacerlo en .Net, debería poder crear una propiedad solo con un getter, pero esto no se actualizará cuando actualice otras propiedades en el cliente si depende de ellas.

+0

Gracias por la respuesta, investigaremos esto esta tarde. Me estaba refiriendo al uso de un observable computarizado knockout ... me preguntaba cómo convierto un ViewModel creado por el complemento de mapeo knockout para agregarle nuevos valores calculados ... ¿lo extiendo de alguna manera? Gracias. –